深入理解JVM:效能分析與監控工具

帥帥的Max發表於2020-12-29

當線上出現問題的時候,最最最重要的是定位問題。一旦定位到問題了,一切都好辦了。但是這個定位問題,需要的不僅僅是理論知識,還需要豐富的實操經驗。而豐富的經驗從哪裡來呢,就是對於工具的運用和資料的分析中來,接下來主要介紹一下虛擬機器中的效能監控以及故障處理工具。

1.概述

通常來說,定位問題最重要的是工具,對於工具的重要性是再怎麼強調都不為過的。然而擁有豐富經驗的大佬,也都是能熟練使用各種工具,就像一位能熟練運用十八般兵器的勇士一樣,面對問題能手到擒來,迅速定位並解決。那麼定位系統問題,離不開相關資料的支援。這些資料包括:執行日誌,異常堆疊,GC日誌,執行緒快照(threaddump/javacore檔案),堆轉儲快照(heapdump/hprof檔案)等。所以資料+工具是解決問題的制勝法寶,但要明確的一點是,沒有包治百病的良藥,也沒有一定萬能的工具。

2.JDK命令列工具

先來看看jdk目錄下的工具(基於jdk1.8.0_201):
JDK自帶工具展示
再來看看tools裡面具體狀況:
JDK自帶tools
接下來介紹幾個比較常用的處理工具

名稱主要作用
jpsJVM Process Status Tool 顯示指定系統內所有的HotSpot虛擬機器程式
jstatJVM Statistics Monitoring Tool 用於收集HotSpot各方面執行資料
jinfoConfiguration Info for Java 顯示虛擬機器配置資訊
jmapMemory Map for Java 生成虛擬機器的記憶體轉儲快照
jhatJVM Heap Dump Browser 用於分析heapdump檔案,它會建立一個http伺服器,讓使用者在網頁上檢視分析結果
jstackStack Trace for Java 顯示虛擬機器的執行緒快照

2.1jps:虛擬機器程式狀況工具

主要用於列出當前虛擬機器執行的程式等資訊。與ps -aux | grep java 類似。

#命令格式
jps [options] [hostid]
#幾種常用的例子
jps 直接輸出當前執行中的虛擬機器程式
jsp -l 可輸出主類的全名,如果進行執行的是Jar包,輸出Jar路徑
jps -v 輸出虛擬機器程式啟動時的JVM引數(重要,重要,重要)

上面的命令都比較簡單,雖然比較簡單,確是使用頻率非常高的一個命令,比如需要輸出虛擬機器的執行引數,就可以通過jps -v輸出,操作起來對線上虛擬機器也沒有什麼影響,可放心使用。

2.2jstat:虛擬機器統計資訊監視工具

命令介紹

主要使用者監控虛擬機器各種執行狀態資訊,包括類裝載,記憶體,垃圾收集,JIT編譯等執行資料。

#jstat命令格式
jstat [option vmid [interval[s|ms] [count] ]
#舉個例子
jstat -gc 2756 250 20 
每250毫秒查詢一次垃圾回收情況,一共查詢20次。2756是程式號。

選項的option代表著使用者希望查詢的虛擬機器資訊,主要分為:類裝載,垃圾收集,執行期編譯狀況。

選項作用
-class監視類裝載,解除安裝數量,總空間以及類裝載所耗費的時間
-gc監視Java堆狀況,包括Eden區,兩個survivor區,老年代,元空間等容量,已用空間,GC時間等合計資訊
-gccapacity與-gc基本相同,主要關注Java堆各區域使用到的最大,最小空間
-gcutil與-gc基本相同,主要關注已使用空間佔比情況
-gccause與-gc基本相同,額外輸出導致上一次gc的原因
-gcnew監視新生代GC狀況
-gcnewcapacity與-gcnew基本相同,輸出主要關注使用到的最大,最小空間
-gcold監視老年代GC狀況
-gcoldcapacity與-gcold基本相同,輸出主要關注使用到的最大,最小空間
-gcmetacapacity監視元空間GC狀況
-compiler輸出JIT編譯過的方法,耗時等資訊
-printcompilation輸出已經被JIT編譯的方法

命令使用

  1. 檢視類載入統計情況
jstat -class [pid]

類載入資訊情況

loaded:載入的class數量
Bytes:所佔用空間大小
Unloaded:未載入class數量
Bytes:未載入class佔用空間
Time:時間

  1. 檢視編譯統計情況
jstat -compiler [pid]

編譯統計情況

Compiled:編譯數量
Failed:失敗數量
Invalid:不可用數量
Time:時間
FailedType:失敗型別
FailedMethod:失敗方法

  1. 垃圾回收統計情況
jstat -gc [pid]

垃圾回收統計情況

S0C:第一個倖存區的大小
S1C:第二個倖存區的大小
S0CU:第一個倖存區的使用大小
S1CU:第二個倖存區的使用大小
EC:伊甸園區的大小
OC:老年代大小
OU:老年代使用大小
MC:方法區大小
MU:方法區使用大小
CCSC:壓縮類空間大小
CCSU:壓縮類空間使用大小
YGC:年輕代垃圾回收次數
YGCT:年輕代垃圾回收消耗時間
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

  1. 堆記憶體統計
jstat -gccapacity [pid]

堆記憶體統計

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:當前新生代容量
S0C:第一個倖存區大小
S1C:第二個倖存區大小
EC:伊甸園區的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:當前老年代大小
OC:老年代大小
MCMN:最小後設資料容量
MCMX:最大後設資料容量
MC:當前後設資料空間大小
CCSMN:最小壓縮類空間大小
CCSMX:最大壓縮類空間大小
CCSC:當前壓縮類空間大小
YGC:年輕代gc次數
FGC:老年代gc次數

  1. 新生代垃圾回收統計
jstat -gcnew [pid]

新生代垃圾回收統計

S0C:第一個倖存區大小
S1C:第二個倖存區大小
S0U:第一個倖存區使用大小
S1U:第二個倖存區使用大小
TT:物件在新生代存活的次數
MTT:物件在新生代中存活的最大次數
DSS:期望的倖存區大小
EC:伊甸園區的大小
EU:伊甸園區的使用大小
YGC:年輕代垃圾回收的次數
YGCT:年輕代垃圾回收消耗時間

  1. 老年代垃圾回收統計
jstat -gcold [pid]

老年代垃圾回收統計

MC:方法區大小
MU:方法區使用大小
CCSC:壓縮類空間大小
CCSU:壓縮類空間使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年輕代垃圾回收次數
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收耗時
GCT:垃圾回收總耗時

  1. 後設資料空間統計
jstat -gcmetacapacity [pid]

元空間統計

MCMN:最小後設資料容量
MCMX:最大後設資料容量
MC:當前後設資料空間大小
CCSMN:最小壓縮類空間大小
CCSMX:最大壓縮類空間大小
YGC:年輕代垃圾回收次數
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

  1. 總結垃圾回收統計
jstat -gcuitl [pid]

總結垃圾回收統計

S0:倖存區1當前使用比例
S1:倖存區2當前使用比例
E:伊甸園區使用比例
O:老年代使用比例
M:後設資料使用比例
CCS:壓縮使用比例
YGC:年輕代垃圾回收次數
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

2.3jinfo:檢視JVM配置資訊工具

這個命令工具的作用是實時的檢視和調整虛擬機器的各項引數。
jinfo的格式:

jinfo [option] pid

2.4jmap:JVM記憶體對映工具

這個命令工具的主要作用是用於生成堆轉儲快照(一般稱為heapdump或者dump檔案),大部分情況下,出現記憶體或者CPU異常情況,都是通過手動的方式dump出記憶體快照。不過虛擬機器引數一般會配置-XX:+HeapDumpOnOutOfMemoryError引數,當虛擬機器出現OOM的情況下,會自動dump記憶體快照檔案。
jmap的命令格式:

jmap [option] vmid

常用選項的含義如下:

選項作用
-dump生成dump檔案,例如: jmap -dump:live,format=b,file=xxx.hprof [pid]
-heap顯示java堆詳細資訊,那種回收器,引數配置,分代狀況等
-histo顯示堆中物件統計資訊,包括類,例項數量,合計容量

2.5jstack:java堆疊跟蹤工具

jstack工具的作用是生成虛擬機器當前時刻的執行緒快照(一般稱為threaddump或者javacore檔案),生成執行緒快照的主要原因是排查執行緒出現長時間停頓,例如執行緒間死鎖,死迴圈等。
jstack的命令格式:

jstack [option] vmid

使用jstack匯出當前執行緒快照:

jstack 3321 > 3321.log

相關文章