Content
1. 背景
給一個系統定位問題的時候,知識、經驗是關鍵基礎,數據(運行日誌、異常堆棧、GC日誌、線程快照[threaddump / javacore文件]、堆轉儲快照[heapdump / hprof])是依據,工具是運用知識處理數據的手段。
經常使用適當的虛擬機監控和分析的工具可以加快我們分析數據、定位解決問題的速度。
2. jps
jps(JVM Process Status Tool)可以列出正在運行的虛擬機進程,並顯示虛擬機執行主類(Main Class,main()函數所在的類)名稱以及這些進程的本地虛擬機唯一ID(Local Virtual Machine Identifier,LVMID)。對於本地虛擬機進程來說,LVMID與操作系統的進程ID(Process Identifier, PID)是一致的。
2.1 用法
主要選項
選項 | 作用 | 備註 |
-q | 只輸出LVMID,省略主類的名稱 | |
-m | 輸出虛擬機進程啓動時傳遞給主類main()函數的參數 | |
-l | 輸出主類的全名,如果進程執行的是jar包,輸出jar路徑 | |
-v | 輸出虛擬機進程啓動時JVM參數 |
3. jstat
3.1 用法
jstat(JVM Statistics Monitoring Tool)是用於監視虛擬機各種運行狀態信息的命令行工具。
它可以顯示本地或遠程虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
jstat [option vmid [interval][s|ms] [count]]
option代表用戶希望查詢的虛擬機信息,主要分爲3類:類裝載、垃圾收集、運行期編譯狀況。具體如下表:
選項 | 作用 |
-class |
監視類裝載、卸載數量、總空間以及類裝載所耗費的時間。 Loaded:加載class的數量; Bytes:所佔用空間大小; Unloaded:未加載數量; Bytes:未加載佔用空間; Time:加載耗時。 |
-gc |
監視Java堆狀況,包括Eden區、兩個Survivor區、老年區、元數據等的容量、已用空間,GC時間合計等信息。 S0C,S1C,EC,OC,MC,CCSC:S0,S1,Eden,老年代,Metaspace和壓縮類空間大小; S0U,S1U,EU,OU,MU,CCSU:S0,S1,Eden,老年代,Metaspace和壓縮類空間已經使用的大小; YGC,YGCT,FGC,FGCT:Young GC和Full GC的次數和耗時; GCT:垃圾回收的耗時。 |
-gccapacity |
監視內容與-gc基本相同,但輸出主要關注Java堆各個區域使用到的最大、最小空間。 NGCMN,NGCMX,NGC:新生代最小、最大和當前容量; S0C,S1C,EC:s0,s1,eden區大小; OGCMN,OGCMX,OGC:老年代最小、最大和當前容量; OC:老年代當前容量; MCMN,MCMX,MC:元數據最小、最大和當前容量; CCSMN,CCSMX,CCSC:壓縮類空間的最小、最大和當前容量; YGC,FGC:minor GC和full GC的次數。 |
-gcutil |
監視內容與-gc基本相同,但輸出主要關注已使用空間佔總空間的百分比。 S0,S1(標示Survivor0,Survivor1):使用了0%; E(新生代Eden區):使用了5.78%; O(老年代):使用了16.92%; M(元空間Metaspace):使用了91.97%; CCS:壓縮使用81.54%; YGC(標示Young GC),YGCT:程序運行以來共發生Minor GC651次,總耗時4.446秒; FGC(標示Full GC),FGCT:Full GC640次,總耗時86.409秒; GCT(GC Time):所有GC耗時爲90.855。 |
-gccause |
與-gcutil功能一樣,但是會額外輸出導致上一次GC產生的原因。 |
-gcnew |
監視新生代GC狀況。 S0C,S1C,S0U,S1U,EC,EU,YGC,YGCT同上; TT:對象在新生代存活的次數; MTT:對象在新生代存活的最大次數; |
-gcnewcapacity |
監視內容與-gcnew基本相同,輸出主要關注使用到的最大、最小空間。 同上 |
-gcold |
監視老年代GC狀況。 |
-gcoldcapacity |
監視內容與-gcold基本相同,輸出主要關注使用到的最大、最小空間。 |
-gcmetacapacity |
輸出元數據(Metaspace)使用到的最大、最小空間。
|
-compiler |
輸出JIT編譯器編譯過的方法、耗時等信息。 Compiled:編譯方法數量; Failed:失敗數量; Invalid:不可用數量; Time:編譯耗時; FailedType:失敗類型; FailedMethod:失敗的方法。 |
-printcompilation |
輸出已經被JIT編譯的方法。 Compiled:最近編譯方法的數量; Size:最近編譯方法的字節碼數量; Type:最近編譯方法的編譯類型; Method:方法名標識。 |
如果是本地虛擬機進程,則VMID與LVMID是一致的,如果是遠程虛擬機進程,那麼VMID的格式是:
[protocal:][//]vmid[@hostname[:port]/servername]
interval代表查詢間隔
count代表查詢次數
如果省略這兩個參數,說明只查詢一次。
4. jinfo(即將廢棄)
jinfo(Configuration Info for Java)的作用是實時地查看和調整虛擬機各項參數。
使用jps -v命令可以查看虛擬機啓動時顯式指定的參數列表,但如果想知道未被顯式指定的參數的系統默認值。
可以使用jinfo的-flag選項進行查詢
4.2 用法
jinfo [option] pid
5. jmap
jmap(Memory Map for Java,Java內存映像工具):命令用於生成堆轉儲快照(heapdump或dump文件)。
-XX:+HeapDumpOnOutOfMemoryError參數,可以讓虛擬機在OOM異常出現之後自動生成dump文件,
通過-XX:+HeapDumpOnCtrlBreak參數則可以使用Ctrl + Break組合鍵讓虛擬機生成dump文件。
jmap還可以查詢finalize執行隊列,Java堆和永久代的詳細信息,如空間使用率,當前用的是哪種收集器等。
說明:除了生成dump文件的-dump選項和用於查看每個類的實例、空間佔用統計的-histo選項在所有操作系統都提供之外,其餘選項都只能在Linux / Solaris使用。
5. 2 用法
jmap [option] vmid
option選項的合法值與具體含義如下表:
選項 | 作用 |
-dump |
生成Java堆轉儲快照,格式爲:-dump[live, ]format=b, file=<filename>,其中live子參數說明是否只dump出存活的對象。 如: jmap -dump:format=b,file=dump.bin 3500 |
-finalizerinfo | 顯示在F-Queue中等待Finalizer線程執行finalize方法的對象。只在Linux/Solaris平臺下有效。 |
-heap | 顯示Java堆詳細信息,如使用哪種回收器,參數配置,分代狀況等。只在Linux/Solaris平臺下有效。 |
-histo | 顯示堆中對象統計信息,包括類,實例數量,合計容量。 |
-permstat | 以ClassLoader爲統計口徑顯示永久代內存狀況,只在Linux/Solaris平臺有效。 |
-F | 當虛擬機進程堆-dump選項沒有響應時,可使用這個選項強制生成dump快照。只在Linux/Solaris平臺有效。 |
注意:更爲詳細的使用可以參考:Java內存分析工具jmap
6. jhat
jhat虛擬機堆轉儲快照分析工具,用來分析jmap生成的堆轉儲快照。
jhat內置了一個微型的HTTP/HTML服務器 ,生成dump文件的分析結果後,可以在瀏覽器中查看。
一般不會直接使用jhat,而是採用更加專業的VisualVM,Eclipse Memory Analyzer,IBM HeapAnalyzer等。
6.1 用法
jhat dump.bin
7. jstack
jstack(Stack Trace for Java):用來生成虛擬機當前時刻的線程快照(稱爲threaddump或javacore文件)。
線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等都是導致線程長時間停頓的常見原因。線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底是後臺做什麼請求,或等待什麼資源。
7.1 用法
jstack [option] vmid
option選項的合法值如下表:
選項 | 作用 |
-F | 當正常輸出的請求不被響應時,強制輸出線程堆棧 |
-l | 除堆棧外,顯示關於鎖的附加信息 |
-m | 如果調用到本地方法的話,可以顯示C/C++的堆棧 |
8. javap
javap是JDK自帶的反彙編器,可以查看java編譯器爲我們生成的字節碼。通過它,我們可以對照源代碼和字節碼,從而瞭解很多編譯器內部的工作。
8.2 用法
語法:
javap [ 命令選項 ] class. . .
javap命令用於解析類文件。其輸出取決於所用的命令選項。若沒有使用命令選項,javap將輸出傳遞給它的類的public 域及方法。javap將其輸出到標準輸出設備上。
命令選項:
-help 輸出 javap 的幫助信息。
-l 輸出行及局部變量表。
-b 確保與 JDK 1.1 javap 的向後兼容性。
-public 只顯示 public 類及成員。
-protected 只顯示 protected 和 public 類及成員。
-package 只顯示包、protected 和 public 類及成員。這是缺省設置。
-private 顯示所有類和成員。
-J[flag] 直接將 flag 傳給運行時系統。
-s 輸出內部類型簽名。
-c 輸出類中各方法的未解析的代碼,即構成 Java 字節碼的指令。
-verbose 輸出堆棧大小、各方法的 locals 及 args 數,以及class文件的編譯版本
-classpath[路徑] 指定 javap 用來查找類的路徑。如果設置了該選項,則它將覆蓋缺省值或 CLASSPATH 環境變量。目錄用冒號分隔。
-bootclasspath[路徑] 指定加載自舉類所用的路徑。缺省情況下,自舉類是實現核心 Java 平臺的類,位於 jrelib下面。
-extdirs[dirs] 覆蓋搜索安裝方式擴展的位置。擴展的缺省位置是 jrelibext。
8.3 實例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
javap -c Test44生成的字節碼爲:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
|