性能分析利器總結二《Arthas》

Arthas

先援引官方一段話:php

Arthas 是Alibaba開源的Java診斷工具,深受開發者喜好。當你遇到如下相似問題而一籌莫展時,Arthas能夠幫助你解決:vue

  • 這個類從哪一個 jar 包加載的?爲何會報各類類相關的 Exception?
  • 我改的代碼爲何沒有執行到?難道是我沒 commit?分支搞錯了?
  • 遇到問題沒法在線上 debug,難道只能經過加日誌再從新發布嗎?
  • 線上遇到某個用戶的數據處理有問題,但線上一樣沒法 debug,線下沒法重現!
  • 是否有一個全局視角來查看系統的運行情況?
  • 有什麼辦法能夠監控到JVM的實時運行狀態?
  • Arthas採用命令行交互模式,同時提供豐富的 Tab 自動補全功能,進一步方便進行問題的定位和診斷。

而後上個圖吧:java

圖上能夠看到Arthas支持的命令,各個命令的具體使用可參見官方文檔:alibaba.github.io/arthas。git

這裏爲何把Arthas這個東西拿出來講,是由於:儘管VisualVM已經在轉儲、監控、快照等方面作得很到位了,可是對於某些領域,它仍有不足!這時候,Arthas能夠發揮一下它的優點。具體領域體如今:github

  • thread 可直接查看線程的cpu佔用比(前篇文件也可看出,VisualVM查看線程cpu佔比有些麻煩)
  • redefine 加載外部class文件到應用程序中(VisualVM沒有這個功能,插件市場貌似也沒有找到相關插件)
  • monitor 監測方法調用次數、成功次數、失敗次數、平均RT等
  • watch tt 觀測方法執行的前、後、結束、異常、耗時過大時,入參(入參屬性深度可調)、返回值、異常,支持實時監測每次方法執行和方法的全部調用執行。
  • jad 反編譯class文件(再也不須要從jar解壓出來,再使用jad工具反編譯了)
  • sc sm 快速搜索類和方法信息
  • getstatic 查看類靜態變量(VisualVM只能看實例屬性)
  • sysprop 修改系統屬性
  • trace 查看方法調用樹耗時,VisualVM也能夠看,不過VisualVM感受更像是從全局來找某個線程的某個方法耗時,而Arthas可直接定位到某個方法進行觀測,而且支持設置條件打印,如耗時超過某值、入參是某值時等等。
  • stack 查看方法的全部調用樹路徑,一樣,VisualVM其實也能看,不過仍然感受是全局找局部,而Arthas是局部方法直接定位,也一樣支持設置條件,當耗時超過某值等才輸出調用該方法的全部調用路徑。

總結一下就是:VisualVM和Arthas能夠相輔相成,前者更像一個全局監測官,監控總體運做狀況!然後者更像一個局部調試官,可監測方法,甚至可細化到方法執行先後的參數等,因此它更經常使用於調試排查bash

基本命令和參數

下面說一下我經常使用的基本命令:app

  • help 查看命令幫助,eg:help getstatic
  • cls 清屏
  • quit 退出當前Arthas客戶端
  • shutdown 退出全部打開的Arthas客戶端

下面說一下我經常使用的基本參數:yii

  • -n 限制打印的條數,如程序執行中,可能有些方法會瘋狂打印。
  • -i 設置打印間隔時間,單位毫秒
  • -x 屬性遍歷深度,默認爲1

經常使用表達式:ide

  • * 任意多個任意字符
  • #cost 消耗的時間

查看線程cpu佔比

thread -n 3 //查看cpu佔比前三的線程
thread -i 1000 //間隔
複製代碼

加載外部class

redefine -p d://tmp/Test.class //加載指定位置的class文件
redefine -c 256a485d -p d://tmp/Test.class //讓指定的classloader來加載,256a485d爲該classloader的hashcode,可經過classloader命令來查得
複製代碼

監測方法的調用次數、成功次數等

monitor -c 5 cn.localhost01.* check  //統計週期5秒,默認120秒
複製代碼

監測方法的入參返回等

實時檢測方法單次執行

watch cn.localhost01.* check "params,reurnObj" -x 2 -b -s  //同時檢測方法調用先後的入參和返回值,參數和返回值的屬性遍歷深度爲2,一共可支持設置 -b(調用前)、 -e(異常時)、-s(返回後)、-f(結束後)
watch cn.localhost01.* check "params,returnObj" "params[0].name.equals('abc')" -x 3 -b  //知足條件纔打印
watch cn.localhost01.* check "params,returnObj" #cost>200 -x 3 //知足條件纔打印
複製代碼

檢測記錄方法全部執行

tt -t -n 20 cn.localhost01.* check
複製代碼

記錄了一段時間後,須要對一些方法進行查看:svn

tt -l  //-list,查看全部記錄的方法,結果集會展現出每一個方法的INDEX索引序號
複製代碼

找出某個方法:

tt -s method.name="check"  //-search,查看方法名爲check的方法
複製代碼

根據INDEX精肯定位到某個方法:

tt -i 1001  //-index,查看索引爲1001的方法
複製代碼

重作一個調用

tt -i 1001 -p  //-play,重執行
複製代碼

反編譯

jad cn.localhost01.demo.Checker
複製代碼

快速搜索

sc cn.*.Checker  //搜索類

sm *.Checker check //搜索方法
複製代碼

查看靜態變量

getstatic *.Checker pool  //注意,查不到常量
複製代碼

修改系統屬性

sysprop java.version 1.7
複製代碼

查看方法調用樹耗時

trace cn.loacalhost01.* check params.length==2  //查看含有兩個參數的check方法調用樹耗時
trace cn.loacalhost01.* check #cost>500 //查看耗時超過500毫秒的check方法調用樹耗時
複製代碼

查看方法全部調用樹路徑

stack cn.loacalhost01.* check params[0]==78  //查看第一個參數值爲78的check方法調用樹耗時
stack cn.loacalhost01.* check #cost>500 //查看耗時超過500毫秒的check方法調用樹耗時
複製代碼

注意

  1. 由上可知,咱們會常常用到命令 classpath methodname,而對於method,若是含有重載,若是區分要監測的具體是哪一個方法呢?

    • tt -t cn.localhost01.* check "params.length==2" //含有兩個參數的方法
    • tt -t cn.localhost01.* check "params[0] instanceof String" //第一個參數必須是String類型
    • tt -t cn.localhost01.* check "params[1].password='123456'" //第二個參數值對象的password屬性值爲123456
  2. idea運行應用程序時,有時as.bat pid打開後,檢測的並非輸入的pid,多是一個bug吧!

相關文章
相關標籤/搜索