Java調優(yōu)系列之工具篇之btrace叨吮、gperftools

Java調優(yōu)系列之工具篇之btrace、gperftools

landon 網絡游戲資深服務器架構師
2018-06-14

線上遇到了問題昭抒?

  1. 服務上線出問題评也,想增加打印日志怎么辦?
  2. 線上懷疑某個接口慢灭返,想打印接口耗時怎么辦盗迟?
  3. 線上某個接口報錯,想看看調用的參數和誰調用了怎么辦熙含?
  4. 線上出錯了罚缕,想看某個對象的數據怎么辦?
  5. 線上出錯了怎静,想看一下jvm的一些信息怎么辦邮弹?
  6. 不確定線上某一行代碼執(zhí)行了怎么辦?
  7. ......

傳統(tǒng)解決方案

  • 修改源代碼 -> 增加相關打印日志 -> hotswap
  • Thread.dumpStack
  • beanshell可以查看內存數據
  • jvm信息可以通過jvm內置命令去獲取
  • 缺點
    • 代碼侵入式
    • 不靈活
    • 源代碼冗余
    • 如果你的服務不支持hotswap呢蚓聘?

什么是btrace

  • BTrace is a safe, dynamic tracing tool for the Java platform.
  • BTrace can be used to dynamically trace a running Java program (similar to DTrace for OpenSolaris applications and OS). BTrace dynamically instruments the classes of the target application to inject tracing code ("bytecode tracing").
  • 江南白衣
    • Btrace是神器腌乡,每一個需要每天解決線上問題,但完全不用Btrace的工程師夜牡,都是可疑的

btrace基礎

  1. https://github.com/btraceio/btrace
    • 以前sun開源的項目
  2. 下載
    • bin 加入環(huán)境變量
    • build 實現(xiàn)包和依賴包
    • samples 示例腳本
    • docs 幫助文檔
  3. 基礎使用
    • IDE下編寫btrace腳本
    • jps找到運行的java進程pid
    • btrace pid btracescript

btrace腳本編寫基礎事項

  1. IDE編寫要引入依賴jar
    • btrace-agent.jar
    • btrace-boot.jar
    • btrace-client.jar
  2. 腳本就是一個.java源文件
  3. @BTrace注解
  4. trace的class要用full name
  5. 只能使用btrace提供的方法与纽,不能自己隨意調用(保證性能不受影響,trace才更放心)

btrace實戰(zhàn)

  1. 一個簡單的偏游戲業(yè)務的sample
  2. btrace
    • Locate 定位trace的方法
    • Intercept 對定位到的方法進行攔截
    • Print 打印需要的數據
  3. 典型場景
    • 找出最耗時的業(yè)務方法
    • 打印調用堆棧
    • ......

btrace#locate

  1. TraceLocate.java
  2. 舉例
    • @OnMethod(clazz = "/practice./", method = "/./")
    • @OnMethod(clazz = "+practice.IHandler", method = "/.*/")
    • @OnMethod(clazz = "/practice.*/", method = "@practice.LogicMethod")
    • @OnMethod(clazz = "/practice.*/", method = "<init>")
  3. 看示例代碼

btrace#intercept

  1. TraceIntercept.java
  2. 舉例
    • @OnMethod(clazz = "practice.LoginHandler", method = "login", location = @Location(Kind.ENTRY))
    • @OnMethod(clazz = "practice.LoginHandler", method = "login", location = @Location(Kind.RETURN))
    • @OnMethod(clazz = "+practice.IHandler", method = "/.*/", location = @Location(Kind.THROW))
    • @OnMethod(clazz = "practice.LoginHandler", method = "login", location = @Location(value = Kind.CALL, clazz = "/./", method = "/./", where = Where.AFTER))
    • @OnMethod(clazz = "practice.HeroHandler", method = "starUp", location = @Location(value = Kind.LINE, line = 16))
  3. 看示例代碼

btrace#print

  1. TracePrint.java
  2. 舉例
    • printMethodSignature
    • AnyType
    • Field field = BTraceUtils.field("practice.PlayerService", "playerMap")
    • @TLS thread local share
  3. 看示例代碼

btrace#TypicalScenes

  1. TraceTypicalScenes.java
  2. 舉例
    • @Duration long duration
      • 納秒
      • Kind.RETURN
    • BTraceUtils.jstack
    • OnTimer
    • jvm
      • jinfo/jmap/...
      • sizeof/deadlock
  3. 示例代碼和自帶sample

btrace原理

  1. Client(Java compile api + attach api) + Agent(腳本解析引擎 + ASM + JDK6 Instumentation) + Socket
  2. java attach api附加agent.jar + 腳本解析引擎+asm來重寫指定類的字節(jié)碼 + instrument實現(xiàn)對原有類的替換
  3. 通過JVM Attach API塘装,btrace把自己綁進了被監(jiān)控的進程 -> 按照腳本定義 -> AOP代碼植入

btrace原理圖解

image

btrace注意的問題

  1. 限制
    • 為了保證性能不受影響急迂,Btrace不允許調用任何實例方法,必須使用btrace提供的api
  2. BTrace植入過的代碼蹦肴,會一直在
  3. 屬于“事后工具” 袋毙,即服務已經上線了,無法再通過打印日志等方式埋點分析
  4. 無法trace native
  5. 一定要用IDE寫btrace腳本
  6. 其他
    • 有一些腳本細節(jié)需要自行體會 如追蹤異常的上下文
    • 可以遠程冗尤、可用于線上生成環(huán)境 還有許多其他命令參數如指定文件輸出

其他工具和參考

  1. 其他類似工具(可能更強大 但是我個人還是偏向sun的btrace)
  2. 參考

gperftools

  1. 場景
    • 主要分析Java的堆外內存泄露
  2. Java進程占用內存
    • Note that the JVM uses more memory than just the heap. For example Java methods, thread stacks and native handles are allocated in memory separate from the heap, as well as JVM internal data structures
  3. 堆外內存
    • jni
    • nio direct buffer

gperftools#install

  1. 下載地址
  2. install
    • Perftools was developed and tested on x86 Linux systems, and it works in its full generality only on those systems. However, we've successfully ported much of the tcmalloc library to FreeBSD, Solaris x86, and Darwin (Mac OS X) x86 and ppc; and we've ported the basic functionality in tcmalloc_minimal to Windows. See INSTALL for details.See README_windows.txt for details on the Windows port.
    • 強烈建議直接在linux安裝听盖,mac文檔少,windows不考慮
  3. linux注意問題

堆外內存泄露sample

  1. NonHeapLeakExample.java
    • java.util.zip.Deflater
  2. javac -> jar -> run.sh
    • javac NonHeapLeakExample.java
    • jar cvf NonHeapLeak.jar NonHeapLeakExample.class
    • java -cp ./NonHeapLeak.jar NonHeapLeakExample
  3. top/jmap/jstat
  4. 示例代碼和腳本

gperftools排查

  1. java啟動腳本增加參數
    • export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
    • export HEAPPROFILE=/tmp/nonheapleak
  2. 啟動輸出
    • Starting tracking the heap
  3. 查看heap是否生成
    • $ ll /tmp | grep .heap
    • -rw-rw-r-- 1 playcrab playcrab 1048574 Jun 13 16:24 nonheapleak_28759.0001.heap
  4. 分析heap
    • pprof --text $JAVA_HOME/bin/java /tmp/nonheapleak_28759.0001.heap

gperftools結果展示

  1. 結果展示
Using local file /data/home/user00/playcrab/usr/jdk/bin/java.
Using local file /tmp/nonheapleak_28759.0003.heap.
Total: 300.2 MB
   281.9  93.9%  93.9%    281.9  93.9% deflateInit2_
    17.7   5.9%  99.8%     17.7   5.9% os::malloc@907360
     0.3   0.1%  99.9%      0.3   0.1% readCEN
     0.1   0.0% 100.0%    282.0  94.0% Java_java_util_zip_Deflater_init
......
  1. 分析
    • Java_java_util_zip_Deflater_init是一個jni方法 對應java方法
    • 可以看到這塊占用內存占用很大

如何找到誰調用了Deflater皆看?

  1. btrace派上用場
@OnMethod(clazz = "java.util.zip.Deflater", method = "<init>")
     public static void traceStack() {
         BTraceUtils.jstack();
     }
  1. 有了Java的調用堆棧,就好辦了
  2. 原因
    • deflater沒有調用end
    • deflater的底層實現(xiàn)全部是調用jni
    • 只申請了內存但是沒有釋放

源代碼

  1. btrace-sample
  2. NonHeapLeak-sample

Q & A

  • 演示過程中背零,貌似gperftools的heap沒生成腰吟,進程kill的時候生成了
    • 可以生成 不過得等一下
    • 從輸出看 是差不多6分鐘左右 heap文件才生成
$ date
2018年 06月 14日 星期四 22:39:43 CST
[playcrab@achilles landon]$ sh nonHeapLeak.sh
$ ll /tmp/*.heap
-rw-rw-r-- 1 playcrab playcrab 1048562 6月  14 22:45 /tmp/nonheapleak_10821.0001.heap
-rw-rw-r-- 1 playcrab playcrab 1048563 6月  14 22:51 /tmp/nonheapleak_10821.0002.heap

  • 關于btrace的注入問題
1. btrace注入的代碼確實一直都在
2. 沒有辦法移除 因為再次寫腳本也是在注入后的基礎上
3. 通常來說線上排查問題 我們不會寫如定位線上所有的業(yè)務方法都進行攔截 肯定會有選擇性的 另外和源代碼增加日志一樣 不會有什么性能問題
4. btraceutils.println是直接發(fā)送到了attach的agent的buff(socket)沒什么問題,client退出了就不會發(fā)了徙瓶,只不過代碼還依然執(zhí)行而已 landon-本質還是socket通訊
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末毛雇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侦镇,更是在濱河造成了極大的恐慌灵疮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壳繁,死亡現(xiàn)場離奇詭異震捣,居然都是意外死亡,警方通過查閱死者的電腦和手機闹炉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門蒿赢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渣触,你說我怎么就攤上這事羡棵。” “怎么了嗅钻?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵皂冰,是天一觀的道長。 經常有香客問我啊犬,道長灼擂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任觉至,我火速辦了婚禮剔应,結果婚禮上,老公的妹妹穿的比我還像新娘语御。我一直安慰自己峻贮,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布应闯。 她就那樣靜靜地躺著纤控,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碉纺。 梳的紋絲不亂的頭發(fā)上船万,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天刻撒,我揣著相機與錄音,去河邊找鬼耿导。 笑死声怔,一個胖子當著我的面吹牛,可吹牛的內容都是我干的舱呻。 我是一名探鬼主播醋火,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箱吕!你這毒婦竟也來了芥驳?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤茬高,失蹤者是張志新(化名)和其女友劉穎兆旬,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體雅采,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡爵憎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了婚瓜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宝鼓。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巴刻,靈堂內的尸體忽然破棺而出愚铡,到底是詐尸還是另有隱情,我是刑警寧澤胡陪,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布沥寥,位于F島的核電站,受9級特大地震影響柠座,放射性物質發(fā)生泄漏邑雅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一妈经、第九天 我趴在偏房一處隱蔽的房頂上張望淮野。 院中可真熱鬧,春花似錦吹泡、人聲如沸骤星。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洞难。三九已至,卻和暖如春揭朝,著一層夾襖步出監(jiān)牢的瞬間队贱,已是汗流浹背色冀。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留柱嫌,地道東北人呐伞。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像慎式,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子趟径,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容

  • 一瘪吏,apk以進程的形式運行,進程的創(chuàng)建是由zygote蜗巧。 參考文章《深入理解Dalvik虛擬機- Android應...
    Kevin_Junbaozi閱讀 2,840評論 0 12
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理掌眠,服務發(fā)現(xiàn),斷路器幕屹,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 簡介 BTrace是一個安全的JVM動態(tài)追蹤工具蓝丙,最初為原Sun公司Kenai項目下面的一個子項目。 典型的使用場...
    lfckop閱讀 5,619評論 10 13
  • 為什么要有Btrace? 生產環(huán)境系統(tǒng)發(fā)生問題時望拖,定位問題需要獲取系統(tǒng)運行時的相關數據渺尘,如方法參數、返回值说敏、全局變...
    jerrik閱讀 888評論 0 2
  • 心里放不下鸥跟,昨晚看了一夜同學們的日志,白天整個人恍恍惚惚的盔沫。矛盾医咨,焦慮充斥了我整個人,告訴自己架诞,都已經退群了拟淮,放棄...
    卜芳閱讀 140評論 1 1