主頁 > 後端開發 > Arthas使用教程 阿里巴巴開源專案、史上最強java線上診斷工具

Arthas使用教程 阿里巴巴開源專案、史上最強java線上診斷工具

2021-07-21 13:27:52 後端開發

在這里插入圖片描述

什么是 Arthas

摘錄一段官方 Github 上的簡介
Arthas 是Alibaba開源的Java診斷工具,深受開發者喜愛,
當你遇到以下類似問題而束手無策時,Arthas 可以幫助你解決:

  • 這個類從哪個 jar 包加載的?為什么會報各種類相關的 Exception?
  • 我改的代碼為什么沒有執行到?難道是我沒 commit?分支搞錯了?
  • 遇到問題無法在線上 debug,難道只能通過加日志再重新發布嗎?
  • 線上遇到某個用戶的資料處理有問題,但線上同樣無法 debug,線下無法重現!
  • 是否有一個全域視角來查看系統的運行狀況?
  • 有什么辦法可以監控到JVM的實時運行狀態?

Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令列互動模式,同時提供豐富的 Tab 自動補全功能,進一步方便進行問題的定位和診斷,

Arthas 基于哪些工具開發而來

  • greys-anatomy: Arthas代碼基于Greys二次開發而來,非常感謝Greys之前所有的作業,以及Greys原作者對Arthas提出的意見和建議!
  • termd: Arthas的命令列實作基于termd開發,是一款優秀的命令列程式開發框架,感謝termd提供了優秀的框架,
  • crash: Arthas的文本渲染功能基于crash中的文本渲染功能開發,可以從這里看到原始碼,感謝crash在這方面所做的優秀作業,
  • cli: Arthas的命令列界面基于vert.x提供的cli庫進行開發,感謝vert.x在這方面做的優秀作業,
  • compiler: Arthas里的記憶體編繹器代碼來源
  • Apache Commons Net: Arthas里的Telnet Client代碼來源
  • JavaAgent:運行在 main方法之前的攔截器,它內定的方法名叫 premain ,也就是說先執行 premain 方法然后再執行 main 方法
  • ASM:一個通用的Java位元組碼操作和分析框架,它可以用于修改現有的類或直接以二進制形式動態生成類,ASM提供了一些常見的位元組碼轉換和分析演算法,可以從它們構建定制的復雜轉換和代碼分析工具,ASM提供了與其他Java位元組碼框架類似的功能,但是主要關注性能,因為它被設計和實作得盡可能小和快,所以非常適合在動態系統中使用(當然也可以以靜態方式使用,例如在編譯器中)

唯一可惜的是,arthas沒有jmap -histo功能,此功能可以在線列印所有物件的數量和占用記憶體大小

啟動

啟動命令

java -jar arthas-boot.jar

不用arthas時一定要正常退出,命令如下:

  • quit:只是退出當前的連接,Attach到目標行程上的arthas還會繼續運行,埠會保持開放,下次連接時執行java -jar arthas-boot.jar可以直接連接上,
  • exit:和quit命令一樣的功能;
  • stop:完全退出arthas,

如果是非正常退出,會報下面的錯誤,提示埠占用,原因是上次連接了一個行程,未正常退出,

[ERROR] The telnet port 3658 is used by process 3804 instead of target process 15043, you will connect to an unexpected process.
[ERROR] 1. Try to restart arthas-boot, select process 3804, shutdown it first with running the 'stop' command.
[ERROR] 2. Or try to stop the existing arthas instance: java -jar arthas-client.jar 127.0.0.1 3658 -c "stop"
[ERROR] 3. Or try to use different telnet port, for example: java -jar arthas-boot.jar --telnet-port 9998 --http-port -1

注意: arthas依賴jdk的環境變數,也依賴一些jdk自帶的工具,比如 jps,如果服務器上只有jre環境而沒有jdk環境的話,是沒有jps的,所以arthas也會報錯;

arthas所有命令

啟動arthas后,在命令列輸入help,即可查看命令幫助資訊、當前arthas版本支持的指令,或者查看具體指令的使用說明,所有的命令如下:

基礎命令

命令說明
cls清空當前螢屏區域,
session查看當前會話的資訊,顯示當前系結的pid以及會話id,
reset重置增強類,將被 Arthas 增強過的類全部還原,Arthas 服務端stop時會重置所有增強過的類
version輸出當前目標 Java 行程所加載的 Arthas 版本號
history列印歷史命令,列印出你在使用arthas程序中輸入了哪些命令,
keymap輸出arthas的快捷鍵映射表:

進階命令

命令說明
dashboard查看當前系統的實時資料面板,例如:服務器thread資訊、記憶體memory、GC回收等情況
thread查看執行緒的堆疊資訊
jvm列印出jvm的資訊,包括引數和變數,以及用的jvm名字、系統等等
sysprop查看當前JVM的系統屬性(System Property)
sysenv查看當前JVM的環境屬性(System Environment Variables)
vmoption查看,更新VM診斷相關的引數
perfcounter查看當前JVM的 Perf Counter資訊
logger查看logger資訊,更新logger level(級別)
mbean這個命令可以便捷的查看或監控 Mbean 的屬性資訊,
getstatic通過getstatic命令可以方便的查看類的靜態屬性,使用方法為getstatic class_name field_name,推薦直接使用ognl命令,更加靈活,
ognl執行ognl運算式,此命令可動態執行代碼
sc查看JVM已加載的類資訊,可以查看類在哪個jar包里面
sm查看已加載類的方法資訊
dumpdump 已加載類的 bytecode 到特定目錄
heapdumpdump java heap, 類似jmap命令的heap dump功能,
vmtoolvmtool 利用JVMTI介面,實作查詢記憶體物件,強制GC等功能,
jad反編譯指定已加載類的原始碼
classloader查看classloader的繼承樹,urls,類加載資訊
mcMemory Compiler/記憶體編譯器,編譯.java檔案生成.class,
retransform加載外部的.class檔案,動態重新加載 jvm已加載的類,
redefine加載外部的.class檔案,redefine jvm已加載的類,這個方式只是修改運行時記憶體,class檔案并沒有改變,服務重啟就失效了,推薦使用 retransform 命令
monitor方法執行監控
watch方法執行資料觀測,讓你能方便的觀察到指定方法的呼叫情況,能觀察到的范圍為:回傳值、拋出例外、入參,通過撰寫 OGNL 運算式進行對應變數的查看,
trace方法內部呼叫路徑,并輸出方法路徑上的每個節點上耗時,trace 命令能主動搜索 class-pattern/method-pattern 對應的方法呼叫路徑,渲染和統計整個呼叫鏈路上的所有性能開銷和追蹤呼叫鏈路,
stack輸出當前方法被呼叫的呼叫路徑
tt方法執行資料的時空隧道,記錄下指定方法每次呼叫的入參和回傳資訊,并能對這些不同的時間下呼叫進行觀測
profilerprofiler 命令支持生成應用熱點的火焰圖,本質上是通過不斷的采樣,然后把收集到的采樣結果生成火焰圖,
cat列印檔案內容,和linux里的cat命令類似,
echo列印引數,和linux里的echo命令類似
grep類似傳統的grep命令
base64base64編碼轉換,和linux里的 base64 命令類似,
tee類似傳統的tee命令, 用于讀取標準輸入的資料,并將其內容輸出成檔案,
pwd回傳當前的作業目錄,和linux命令類似
auth驗證當前會話
options系統的配置開關,可開啟和關閉

命令介紹

這里主要介紹常用的arthas命令,不會每個命令都介紹一遍,有些命令是linux繼承過來的,也沒必要介紹,

session 查看當前會話的資訊

這個命令非常簡單,就只是列印行程的pid和會話id,注意是java的行程id,不是arthas的行程id;

[arthas@12771]$ session
 Name        Value                                                                                                                                  
--------------------------------------------------                                                                                                  
 JAVA_PID    12771                                                                                                                                  
 SESSION_ID  41d19baa-2064-442a-acf1-b8ac11801265 

history 列印命令歷史

啟動arthas后,你輸入過的命令都會被記錄起來,history則會列印出你的輸入歷史

  • history 5 :查看最近執行的5條指令
  • history -c:清空輸入的歷史指令

quit 退出當前arthas客戶端

只是退出當前 Arthas 客戶端,其他 Arthas 客戶端不受影響,等同于exit、logout、q三個指令,

stop 關閉 Arthas 服務端

執行stop指令后,所有 Arthas 客戶端全部退出,關閉Arthas服務器之前,會重置掉所有做過的增強類,但是用redefine重加載的類內容不會被重置,

dashboard命令 查看當前系統的實時資料面板

查看當前系統的實時資料面板,例如:服務器thread(執行緒)資訊、記憶體memory、GC回收等情況
在這里插入圖片描述

資料列說明

  • ID: Java級別的執行緒ID,注意這個ID不能跟jstack中的nativeID一一對應,
  • NAME: 執行緒名
  • GROUP: 執行緒組名
  • PRIORITY: 執行緒優先級, 1~10之間的數字,越大表示優先級越高
  • STATE: 執行緒的狀態
  • CPU%: 執行緒的cpu使用率,比如采樣間隔1000ms,某個執行緒的增量cpu時間為100ms,則cpu使用率=100/1000=10%
  • DELTA_TIME: 上次采樣之后執行緒運行增量CPU時間,資料格式為秒
  • TIME: 執行緒運行總CPU時間,資料格式為分:秒
  • INTERRUPTED: 執行緒當前的中斷位狀態
  • DAEMON: 是否是daemon執行緒

JVM內部執行緒

Java 8之后支持獲取JVM內部執行緒CPU時間,這些執行緒只有名稱和CPU時間,沒有ID及狀態等資訊(顯示ID為-1), 通過內部執行緒可以觀測到JVM活動,如GC、JIT編譯等占用CPU情況,方便了解JVM整體運行狀況,

設定重繪間隔和次數

另外,面板會默認會每5秒重繪一次,并且會一直重繪下去,如果想要指定重繪次數和間隔時間,可以這么寫:

dashboard dashboard -i 1000 -n 2

-i表示重繪的間隔時間,單位(毫秒),-n 表表示查詢的次數,到達指定次數后,自動退出dashboard面板;

thread 查看執行緒的堆疊資訊

當沒有引數時,默認顯示第一頁的執行緒資訊:thread
在這里插入圖片描述

查看某個執行緒的堆疊:thread 13,13為執行緒的id

[arthas@12771]$ thread 13
"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" Id=13 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1368)
    at java.lang.Thread.run(Thread.java:748)

除此之外,thread還有其他的用法

  • thread -n 5:列印前5個最忙的執行緒并列印堆疊
  • thread -all :顯示所有匹配的執行緒
  • thread -n 3 -i 1000 :列出1000ms內最忙的3個執行緒堆疊
  • thread –state WAITING,查看指定狀態的執行緒,(TIMED_WAITIWAITINGRUNNABLE等等)
  • thread -b:找出阻塞其他執行緒的執行緒,當出現死鎖后,會提示你出現死鎖的位置,代碼如下
    static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException, IOException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    synchronized (obj) {
                        System.out.println("我是第一個執行緒");
                        Thread.sleep(100000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"yexindong-one").start();

        Thread.sleep(1000);
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj) {
                    System.out.println("我是第二個執行緒");
                }
            }
        },"yexindong-two").start();
    }

在這里插入圖片描述

jvm 查看當前JVM資訊

jvm顯示jvm的資料匯總,具體內容分為以下幾塊

  • runtime: 包括jvm開始時間,啟動引數,class_path等
  • class-loading :已加載類的數量,總共加載類數量,已卸載類的數量
  • garbage-collectors: 顯示使用的垃圾收集器及垃圾收集次數
  • memory :堆記憶體空間使用情況
  • thread: 執行緒總數,守護執行緒數,死鎖數量
thread執行緒相關資訊如下
  • COUNT: JVM當前活躍的執行緒數
  • DAEMON-COUNT: JVM當前活躍的守護執行緒數
  • PEAK-COUNT: 從JVM啟動開始曾經活著的最大執行緒數
  • STARTED-COUNT: 從JVM啟動開始總共啟動過的執行緒次數
  • DEADLOCK-COUNT: JVM當前死鎖的執行緒數

vmoption 查看/更新虛擬機引數

這個命令可以看到我們的java專案在運行時設定了哪些引數,命令沒有引數時會列印所有的vm引數

[arthas@12771]$ vmoption
 KEY                                  VALUE                                ORIGIN                               WRITEABLE                           
----------------------------------------------------------------------------------------------------------------------------------------------------
 HeapDumpBeforeFullGC                 false                                DEFAULT                              true                                
 HeapDumpAfterFullGC                  false                                DEFAULT                              true                                
 HeapDumpOnOutOfMemoryError           false                                DEFAULT                              true                                
 HeapDumpPath                                                              DEFAULT                              true                                
 CMSAbortablePrecleanWaitMillis       100                                  DEFAULT                              true                                
 CMSWaitDuration                      2000                                 DEFAULT                              true                                
 CMSTriggerInterval                   -1                                   DEFAULT                              true                                
 PrintGC                              false                                DEFAULT                              true                                
 PrintGCDetails                       false                                DEFAULT                              true                                
 PrintGCDateStamps                    false                                DEFAULT                              true                                
 PrintGCTimeStamps                    false                                DEFAULT                              true                                
 PrintGCID                            false                                DEFAULT                              true                                
 PrintClassHistogramBeforeFullGC      false                                DEFAULT                              true                                
 PrintClassHistogramAfterFullGC       false                                DEFAULT                              true                                
 PrintClassHistogram                  false                                DEFAULT                              true                                
 MinHeapFreeRatio                     40                                   DEFAULT                              true                                
 MaxHeapFreeRatio                     70                                   DEFAULT                              true                                
 PrintConcurrentLocks                 false                                DEFAULT                              true         

除此之外,還可查看單個引數和動態設定引數功能,這里可以動態更新引數,不需要重啟java行程;

  • vmoption PrintGCDetails 查看指定的vm引數
  • vmoption PrintGCDetails true 更新指定的vm引數

ognl 動態執行代碼

呼叫靜態方法:ognl '@java.lang.System@out.println("hello yexindong")',執行后,可以看到控制臺列印了hello yexindong
在這里插入圖片描述

sc 查看jvm已加載的類資訊

簡單用法sc com.test.Test,如果jvm已加載這個類,則會列印出該類的全類名,

[arthas@3568]$ sc com.test.Test
com.test.Test
Affect(row-cnt:1) cost in 4 ms.

但是這樣的資訊太過于簡陋了, 加上-d引數可以列印類的詳細資訊,并且還可以查看你這個類在哪個jar包里面,命令如下

  sc -d com.test.Test

列印結果如下

[arthas@3568]$ sc -d *.Test
 class-info        com.test.Test                                                
 code-source       /Users/yexindong/Documents/java/java_project/Test/target/cla 
                   sses/                                                        
 name              com.test.Test                                                
 isInterface       false                                                        
 isAnnotation      false                                                        
 isEnum            false                                                        
 isAnonymousClass  false                                                        
 isArray           false                                                        
 isLocalClass      false                                                        
 isMemberClass     false                                                        
 isPrimitive       false                                                        
 isSynthetic       false                                                        
 simple-name       Test                                                         
 modifier          public                                                       
 annotation                                                                     
 interfaces                                                                     
 super-class       +-java.lang.Object                                           
 class-loader      +-sun.misc.Launcher$AppClassLoader@18b4aac2                  
                     +-sun.misc.Launcher$ExtClassLoader@3df8ac7c                
 classLoaderHash   18b4aac2                                                     

Affect(row-cnt:1) cost in 17 ms.

除此之外,還可以使用模糊查詢

  • sc -d *.Test :查詢所有類名為Test的類
  • sc -d com.*:查詢com包下面所有的類,會往所有的子包遍歷

sm 查看已加載的類方法資訊

查詢某個類下所有的方法

[arthas@3568]$ sm com.test.Test
com.test.Test <init>()V
com.test.Test main([Ljava/lang/String;)V
Affect(row-cnt:2) cost in 4 ms.

通過結果可以看到,有2個方法,一個是main方法,另一個為構造方法,如果你未使用構造方法,在編譯的時候會自動生成構造方法;
除此之外,還可以加上-d列印方法的詳細資訊 :sm -d com.test.Test

[arthas@3568]$ sm -d com.test.Test
 declaring-class   com.test.Test                                                
 constructor-name  <init>                                                       
 modifier          public                                                       
 annotation                                                                     
 parameters                                                                     
 exceptions                                                                     
 classLoaderHash   18b4aac2                                                     

 declaring-class  com.test.Test                                                 
 method-name      main                                                          
 modifier         public,static                                                 
 annotation                                                                     
 parameters       java.lang.String[]                                            
 return           void                                                          
 exceptions       java.lang.InterruptedException                                
                  java.io.IOException                                           
 classLoaderHash  18b4aac2                                                      

Affect(row-cnt:2) cost in 6 ms.

另外,還可以列印類中的某一個方法: sm -d com.test.Test main

# 這里列印的是main方法資訊
[arthas@3568]$ sm -d com.test.Test main
 declaring-class  com.test.Test                                                 
 method-name      main                                                          
 modifier         public,static                                                 
 annotation                                                                     
 parameters       java.lang.String[]                                            
 return           void                                                          
 exceptions       java.lang.InterruptedException                                
                  java.io.IOException                                           
 classLoaderHash  18b4aac2                                                      

Affect(row-cnt:1) cost in 4 ms.

dump 將某個類的class位元組碼檔案匯出到指定目錄

這個功能最大的好處就是可以匯出某個指定的類,比如我想要匯出Test.class檔案到 指定目錄,可以這樣寫

dump -d /Users/yexindong/Downloads com.test.Test

在這里插入圖片描述
然后在指定的目錄下就可以看到剛付訓出的class檔案
在這里插入圖片描述
經過反編譯后的class檔案是這樣的
在這里插入圖片描述
另外,也可以使用-c或者--classLoaderClass來匯出指定hashcode 的類加載器加載的類
dump -c 3d4eac69 demo.* 或者 dump --classLoaderClass sun.misc.Launcher$AppClassLoader demo.*

heapdump 匯出堆轉儲檔案

這個命令和jdk自帶的jmap類似,匯出的檔案是一個二進制檔案,匯出命令:heapdump,未指定引數時會匯出所有的類,并且會在磁盤的某個地方自動創建一個臨時目錄,二進制檔案就在那個地方;

[arthas@28747]$ heapdump
Dumping heap to /var/folders/yq/mz0mh34s2s58zpj3sf7c9d800000gn/T/heapdump2021-07-19-16-321079309703341992219.hprof ...
Heap dump file created

如果要只匯出存活的物件,并且存盤到指定的目錄,可以這么寫

heapdump --live /tmp/dump.hprof
  • --live 表示只匯出存活的物件
  • /tmp/dump.hprof 表示匯出到哪個目錄,并制定檔案名稱;

jad 反編譯class檔案

這里的反編譯用起來比較簡單,只需要輸入全類名即可反編譯原始碼:jad com.test.Test,執行jad命令后還會列印出類加載器和class檔案的所在目錄

[arthas@3568]$ jad com.test.Test

ClassLoader:                                                                        
+-sun.misc.Launcher$AppClassLoader@18b4aac2                                         
  +-sun.misc.Launcher$ExtClassLoader@3df8ac7c                                       

Location:                                                                           
/Users/yexindong/Documents/java/java_project/Test/target/classes/                   

       /*
        * Decompiled with CFR.
        */
       package com.test;
       
       import java.io.IOException;
       
       public class Test {
       
           public static void main(String[] args) throws InterruptedException, IOException {
               System.out.println("hello would");
           }
       }

Affect(row-cnt:3) cost in 643 ms.

除此之外jad還可以反編譯類中的某個方法,下面的代碼只編譯main方法,并且不顯示行號,lineNumber默認的值是true,現在我們把它設為false就不顯示行號了;

jad com.test.Test main --lineNumber false

mc 記憶體編譯器,編譯.java檔案生成.class,

使用也非常簡單,mc后面加上需要編譯的java檔案即可

mc /tmp/Test.java

也可以使用--classLoaderClass引數來指定類加載器,加上-d命令來指定輸出目錄

mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp

編譯生成.class檔案之后,可以結合retransform命令實作熱更新代碼,

retransform 加載外部的.class檔案

以下命令即可加載指定的class檔案

retransform /tmp/Test.class

monitor 方法執行監控

執行以下命令既可以啟動對方法的監控,

monitor -c 1 -n 2 com.test.Test show
  • 其中-c 1 表示監控周期,每一秒監控一次,如果不指定,默認是120秒周期
  • -n 2 表示一共監控2次,監控的方法為Test類中的show()方法,如果不指定,將會一直監控下去

監控結果如下
在這里插入圖片描述
監控結果說明

監控項說明
timestamp時間戳
classJava類
method方法(構造方法、普通方法)
total呼叫次數
success成功次數
fail失敗次數
rt平均RT
fail-rate失敗率

watch 方法執行資料觀測

watch命令可以讓用戶能方便的觀察到指定方法的呼叫情況,能觀察到的范圍為:回傳值、拋出例外、入參,通過撰寫 OGNL 運算式進行對應變數的查看,
1、以下命令用于觀察方法出參和回傳值,

watch com.test.Test show "{params,returnObj}" -x 2 -b -e -s -f 
  • 觀察的方法為Test類下的show()方法,
  • "{params,returnObj}"是觀察運算式,是一個ognl運算式,
  • -x 2是指定輸出結果的屬性遍歷深度,默認值為1,為1時看不到引數的具體值,只能看到型別;
  • -b:在方法呼叫之前觀察,用此命令可查看方法的入參
  • -e:在方法例外之后觀察,用此命令可查看方法拋出的例外
  • -s:在方法回傳之后觀察,可查看方法的回傳值
  • -f:在方法結束之后(正常回傳和例外回傳)觀察,可查看方法的回傳值和例外資訊,默認打開-f

在這里插入圖片描述

trace 方法呼叫鏈

trace 命令能主動搜索方法呼叫路徑,,并輸出方法路徑上的每個節點上耗時,渲染和統計整個呼叫鏈路上的所有性能開銷和追蹤呼叫鏈路,

監聽Test類下show方法的呼叫鏈:trace com.test.Test show

[arthas@4805]$ trace com.test.Test show
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 28 ms, listenerId: 2
`---ts=2021-07-18 21:41:52;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2
    `---[0.884064ms] com.test.Test:show()
        `---[0.135646ms] com.test.Test:showChild() #38

通過結果可以看到,在main執行緒中show()方法呼叫了showChild()方法,前面的ms數是呼叫方法所花費的時間,

呼叫鏈屬性說明

  • thread_name :執行緒名稱
  • id:內部執行緒id
  • is_daemon : 是否為守護執行緒
  • priority:執行緒優先級
  • TCCL:類加載器

stack 輸出當前方法被呼叫的呼叫路徑

和trace命令類似,不同的是stack只輸出呼叫路徑,且stack可以通過運算式來過濾,就像下面這個命令,只過濾show方法第一個引數值大于320的方法,-n 2表示過濾2次

stack com.test.Test show 'params[0]>320' -n 2

執行結果

stack com.test.Test show 'params[0]>320' -n 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 17 ms, listenerId: 5
ts=2021-07-18 21:52:01;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2
    @com.test.Test.show()
        at com.test.Test.main(Test.java:27)

....此處省略一次列印資訊

Command execution times exceed limit: 2, so command will exit. You can set it with -n option.

tt 記錄下指定方法每次呼叫的入參和回傳資訊

watch 雖然很方便和靈活,但需要提前想清楚觀察運算式的拼寫,這對排查問題而言要求太高,因為很多時候我們并不清楚問題出自于何方,只能靠蛛絲馬跡進行猜測,

這個時候如果能記錄下當時方法呼叫的所有入參和回傳值、拋出的例外會對整個問題的思考與判斷非常有幫助,

于是乎,TimeTunnel 命令就誕生了,執行方法如下

tt  -t -n 3 com.test.Test show
  • -t 表示這個引數的表明希望記錄下類 Test 的 show() 方法的每次執行情況,
  • -n 3 :當你執行一個呼叫量不高的方法時可能你還能有足夠的時間用 CTRL+C 中斷 tt 命令記錄的程序,但如果遇到呼叫量非常大的方法,瞬間就能將你的 JVM 記憶體撐爆,此時你可以通過 -n 引數指定你需要記錄的次數,當達到記錄次數時 Arthas 會主動中斷tt命令的記錄程序,避免人工操作無法停止的情況,

命令執行結果如下

[arthas@4805]$ tt  -t -n 3 com.test.Test show 
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 16 ms, listenerId: 8
 INDE  TIMESTAMP      COST(  IS-R  IS-E  OBJECT     CLASS                  METHOD               
 X                    ms)    ET    XP                                                           
------------------------------------------------------------------------------------------------
 1045  2021-07-18 21  0.327  true  fals  NULL       Test                   show                 
       :57:15         033          e                                                            
 1046  2021-07-18 21  0.100  true  fals  NULL       Test                   show                 
       :57:17         478          e                                                            
 1047  2021-07-18 21  0.160  true  fals  NULL       Test                   show                 
       :57:19         673          e                                                                                      
結果欄位說明
表格欄位欄位解釋
INDEX時間片段記錄編號,每一個編號代表著一次呼叫,后續tt還有很多命令都是基于此編號指定記錄操作,非常重要,
TIMESTAMP方法執行的本機時間,記錄了這個時間片段所發生的本機時間
COST(ms)方法執行的耗時
IS-RET方法是否以正常回傳的形式結束
IS-EXP方法是否以拋例外的形式結束
OBJECT執行物件的hashCode(),注意,曾經有人誤認為是物件在JVM中的記憶體地址,但很遺憾他不是,但他能幫助你簡單的標記當前執行方法的類物體
CLASS執行的類名
METHOD執行的方法名

profiler 生成火焰圖

啟動profiler

 $ profiler start
 Started [cpu] profiling

獲取已采集的sample的數量

$ profiler getSamples
23

查看profiler狀態,可以查看當前profiler在采樣哪種event和采樣時間

$ profiler status
[cpu] profiling is running for 4 seconds

停止profiler—生成svg格式結果

$ profiler stop
profiler output file: /tmp/demo/arthas-output/20191125-135546.svg
OK

默認情況下,生成的結果保存到應用的作業目錄下的arthas-output目錄,可以通過 --file引數來指定輸出結果路徑,比如:

$ profiler stop --file /tmp/output.svg
profiler output file: /tmp/output.svg
OK

生成html格式結果
默認情況下,結果檔案是svg格式,如果想生成html格式,可以用–format引數指定:

$ profiler stop --format html
profiler output file: /tmp/test/arthas-output/20191125-143329.html
OK

或者在–file引數里用檔案名指名格式,比如–file /tmp/result.html ,
通過瀏覽器查看arthas-output下面的profiler結果
默認情況下,arthas使用3658埠,則可以打開: http://localhost:3658/arthas-output/ 查看到arthas-output目錄下面的profiler結果:
在這里插入圖片描述
點擊可以查看具體的結果:
在這里插入圖片描述

options 全域配置開關

查看所有的options

[arthas@4805]$ options
 LEVEL  TYPE   NAME         VALUE  SUMMARY              DESCRIPTION                             
------------------------------------------------------------------------------------------------
 0      boole  unsafe       false  Option to support s  This option enables to proxy functional 
        an                         ystem-level class    ity of JVM classes. Due to serious secu 
                                                        rity risk a JVM crash is possibly be in 
                                                        troduced. Do not activate it unless you 
                                                         are able to manage.                    
 1      boole  dump         false  Option to dump the   This option enables the enhanced classe 
        an                         enhanced classes     s to be dumped to external file for fur 
                                                        ther de-compilation and analysis.       
 1      boole  batch-re-tr  true   Option to support b  This options enables to reTransform cla 
        an     ansform             atch reTransform Cl  sses with batch mode.                   
                                   ass                                                          
 2      boole  json-format  false  Option to support J  This option enables to format object ou 
        an                         SON format of objec  tput with JSON when -x option selected. 
                                   t output                                                     
 1      boole  disable-sub  false  Option to control i  This option disable to include sub clas 
        an     -class              nclude sub class wh  s when matching class.                  
                                   en class matching                                            
 1      boole  support-def  true   Option to control i  This option disable to include default  
        an     ault-method         nclude default meth  method in interface when matching class 
                                   od in interface whe  .                                       
                                   n class matching                                             
 1      boole  save-result  false  Option to print com  This option enables to save each comman 
        an                         mand's result to lo  d's result to log file, which path is $ 
                                   g file               {user.home}/logs/arthas-cache/result.lo 
                                                        g.                                      
 2      Strin  job-timeout  1d     Option to job timeo  This option setting job timeout,The uni 
        g                          ut                   t can be d, h, m, s for day, hour, minu 
                                                        te, second. 1d is one day in default    
 1      boole  print-paren  true   Option to print all  This option enables print files in pare 
        an     t-fields             fileds in parent c  nt class, default value true.           
                                   lass                                                         
 1      boole  verbose      false  Option to print ver  This option enables print verbose infor 
        an                         bose information     mation, default value false.            
[arthas@4805]$ 

結果欄位說明

名稱默認值描述
unsafefalse是否支持對系統級別的類進行增強,打開該開關可能導致把JVM搞掛,請慎重選擇!
dumpfalse是否支持被增強了的類dump到外部檔案中,如果打開開關,class檔案會被dump到/${application working dir}/arthas-class-dump/目錄下,具體位置詳見控制臺輸出
batch-re-transformtrue是否支持批量對匹配到的類執行retransform操作
json-formatfalse是否支持json化的輸出
disable-sub-classfalse是否禁用子類匹配,默認在匹配目標類的時候會默認匹配到其子類,如果想精確匹配,可以關閉此開關
support-default-methodtrue是否支持匹配到default method,默認會查找interface,匹配里面的default method,參考 #1105
save-resultfalse是否打開執行結果存日志功能,打開之后所有命令的運行結果都將保存到~/logs/arthas-cache/result.log中
job-timeout1d異步后臺任務的默認超時時間,超過這個時間,任務自動停止;比如設定 1d, 2h, 3m, 25s,分別代表天、小時、分、秒
print-parent-fieldstrue是否列印在parent class里的filed
獲取option的值
[arthas@4805]$ options json-format
 LEVEL  TYPE   NAME         VALUE  SUMMARY              DESCRIPTION                             
------------------------------------------------------------------------------------------------
 2      boole  json-format  false  Option to support J  This option enables to format object ou 
        an                         SON format of objec  tput with JSON when -x option selected. 
                                   t output                                                     
設定指定的option
[arthas@4805]$ options save-result true
 NAME         BEFORE-VALUE  AFTER-VALUE                                                         
----------------------------------------                                                        
 save-result  false         true    

arthas目前來說用的人還是非常多的,據說阿里內部的人都在使用這個工具來查找錯誤,目前來說大部分的公司都還在使用 jinfo、jmap、jstack、jhat等jdk自帶的工具來找錯,工具沒有好壞,看你如何使用,只要能達到目的就可以!arthas這個工具的出現, 幫助我們查找故障又多了一種方法;

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/289270.html

標籤:java

上一篇:Java基礎知識總結(超詳細整理)

下一篇:02-Spring Security 安全框架應用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more