JVM(4):Jvm調優-命令篇(選修)
原文出處: 純潔的微笑
運用jvm自帶的命令可以方便的在生產監控和列印堆疊的日誌資訊幫忙我們來定位問題!雖然jvm調優成熟的工具已經有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,但是在生產環境出現問題的時候,一方面工具的使用會有所限制,另一方面喜歡裝X的我們,總喜歡在出現問題的時候在終端輸入一些命令來解決。所有的工具幾乎都是依賴於jdk的介面和底層的這些命令,研究這些命令的使用也讓我們更能瞭解jvm構成和特性。
Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfo下面做一一介紹
jps
JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機器程序。
命令格式
1 |
|
option引數
- -l : 輸出主類全名或jar路徑
- -q : 只輸出LVMID
- -m : 輸出JVM啟動時傳遞給main()的引數
- -v : 輸出JVM啟動時顯示指定的JVM引數
其中[option]、[hostid]引數也可以不寫。
示例
1 2 3 4 |
|
jstat
jstat(JVM statistics Monitoring)是用於監視虛擬機器執行時狀態資訊的命令,它可以顯示出虛擬機器程序中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料。
命令格式
1 |
|
引數
- [option] : 操作引數
- LVMID : 本地虛擬機器程序ID
- [interval] : 連續輸出的時間間隔
- [count] : 連續輸出的次數
option 引數總覽
Option | Displays… |
---|---|
class | class loader的行為統計。Statistics on the behavior of the class loader. |
compiler | HotSpt JIT編譯器行為統計。Statistics of the behavior of the HotSpot Just-in-Time compiler. |
gc | 垃圾回收堆的行為統計。Statistics of the behavior of the garbage collected heap. |
gccapacity | 各個垃圾回收代容量(young,old,perm)和他們相應的空間統計。Statistics of the capacities of the generations and their corresponding spaces. |
gcutil | 垃圾回收統計概述。Summary of garbage collection statistics. |
gccause | 垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因。Summary of garbage collection statistics (same as -gcutil), with the cause of the last and |
gcnew | 新生代行為統計。Statistics of the behavior of the new generation. |
gcnewcapacity | 新生代與其相應的記憶體空間的統計。Statistics of the sizes of the new generations and its corresponding spaces. |
gcold | 年老代和永生代行為統計。Statistics of the behavior of the old and permanent generations. |
gcoldcapacity | 年老代行為統計。Statistics of the sizes of the old generation. |
gcpermcapacity | 永生代行為統計。Statistics of the sizes of the permanent generation. |
printcompilation | HotSpot編譯方法統計。HotSpot compilation method statistics. |
option 引數詳解
-class
監視類裝載、解除安裝數量、總空間以及耗費的時間
1 2 3 |
|
- Loaded : 載入class的數量
- Bytes : class位元組大小
- Unloaded : 未載入class的數量
- Bytes : 未載入class的位元組大小
- Time : 載入時間
-compiler
輸出JIT編譯過的方法數量耗時等
1 2 3 |
|
- Compiled : 編譯數量
- Failed : 編譯失敗數量
- Invalid : 無效數量
- Time : 編譯耗時
- FailedType : 失敗型別
- FailedMethod : 失敗方法的全限定名
-gc
垃圾回收堆的行為統計,常用命令
1 2 3 |
|
C即Capacity 總容量,U即Used 已使用的容量
- S0C : survivor0區的總容量
- S1C : survivor1區的總容量
- S0U : survivor0區已使用的容量
- S1C : survivor1區已使用的容量
- EC : Eden區的總容量
- EU : Eden區已使用的容量
- OC : Old區的總容量
- OU : Old區已使用的容量
- PC 當前perm的容量 (KB)
- PU perm的使用 (KB)
- YGC : 新生代垃圾回收次數
- YGCT : 新生代垃圾回收時間
- FGC : 老年代垃圾回收次數
- FGCT : 老年代垃圾回收時間
- GCT : 垃圾回收總消耗時間
1 |
|
這個命令意思就是每隔2000ms輸出1262的gc情況,一共輸出20次
-gccapacity
同-gc,不過還會輸出Java堆各區域使用到的最大、最小空間
1 2 3 |
|
- NGCMN : 新生代佔用的最小空間
- NGCMX : 新生代佔用的最大空間
- OGCMN : 老年代佔用的最小空間
- OGCMX : 老年代佔用的最大空間
- OGC:當前年老代的容量 (KB)
- OC:當前年老代的空間 (KB)
- PGCMN : perm佔用的最小空間
- PGCMX : perm佔用的最大空間
-gcutil
同-gc,不過輸出的是已使用空間佔總空間的百分比
1 2 3 |
|
-gccause
垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因
1 2 3 |
|
- LGCC:最近垃圾回收的原因
- GCC:當前垃圾回收的原因
-gcnew
統計新生代的行為
1 2 3 |
|
- TT:Tenuring threshold(提升閾值)
- MTT:最大的tenuring threshold
- DSS:survivor區域大小 (KB)
-gcnewcapacity
新生代與其相應的記憶體空間的統計
1 2 3 |
|
- NGC:當前年輕代的容量 (KB)
- S0CMX:最大的S0空間 (KB)
- S0C:當前S0空間 (KB)
- ECMX:最大eden空間 (KB)
- EC:當前eden空間 (KB)
-gcold
統計舊生代的行為
1 2 3 |
|
-gcoldcapacity
統計舊生代的大小和空間
1 2 3 |
|
-gcpermcapacity
永生代行為統計
1 2 3 |
|
-printcompilation
hotspot編譯方法統計
1 2 3 |
|
- Compiled:被執行的編譯任務的數量
- Size:方法位元組碼的位元組數
- Type:編譯型別
- Method:編譯方法的類名和方法名。類名使用”/” 代替 “.” 作為空間分隔符. 方法名是給出類的方法名. 格式是一致於HotSpot – XX:+PrintComplation 選項
jmap
jmap(JVM Memory Map)命令用於生成heap dump檔案,如果不使用這個命令,還闊以使用-XX:+HeapDumpOnOutOfMemoryError引數來讓虛擬機器出現OOM的時候·自動生成dump檔案。 jmap不僅能生成dump檔案,還闊以查詢finalize執行佇列、Java堆和永久代的詳細資訊,如當前使用率、當前使用的是哪種收集器等。
命令格式
1 |
|
option引數
- dump : 生成堆轉儲快照
- finalizerinfo : 顯示在F-Queue佇列等待Finalizer執行緒執行finalizer方法的物件
- heap : 顯示Java堆詳細資訊
- histo : 顯示堆中物件的統計資訊
- permstat : to print permanent generation statistics
- F : 當-dump沒有響應時,強制生成dump快照
示例
-dump
常用格式
1 |
|
dump堆到檔案,format指定輸出格式,live指明是活著的物件,file指定檔名
1 2 3 |
|
dump.hprof這個字尾是為了後續可以直接用MAT(Memory Anlysis Tool)開啟。
-finalizerinfo
列印等待回收物件的資訊
1 2 3 4 5 6 |
|
可以看到當前F-QUEUE佇列中並沒有等待Finalizer執行緒執行finalizer方法的物件。
-heap
列印heap的概要資訊,GC使用的演算法,heap的配置及wise heap的使用情況,可以用此來判斷記憶體目前的使用情況以及垃圾回收情況
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 |
|
可以很清楚的看到Java堆中各個區域目前的情況。
-histo
列印堆的物件統計,包括物件數、記憶體大小等等 (因為在dump:live前會進行full gc,如果帶上live則只統計活物件,因此不加live的堆大小要大於加live堆的大小 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
xml class name
是物件型別,說明如下:
1 2 3 4 5 6 7 8 9 |
|
-permstat
列印Java堆記憶體的永久儲存區域的類載入器的智慧統計資訊。對於每個類載入器而言,它的名稱、活躍度、地址、父類載入器、它所載入的類的數量和大小都會被列印。此外,包含的字串數量和大小也會被列印。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
-F
強制模式。如果指定的pid沒有響應,請使用jmap -dump或jmap -histo選項。此模式下,不支援live子選項。
jhat
jhat(JVM Heap Analysis Tool)命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內建了一個微型的HTTP/HTML伺服器,生成dump的分析結果後,可以在瀏覽器中檢視。在此要注意,一般不會直接在伺服器上進行分析,因為jhat是一個耗時並且耗費硬體資源的過程,一般把伺服器生成的dump檔案複製到本地或其他機器上進行分析。
命令格式
1 |
|
引數
- -stack false|true 關閉物件分配呼叫棧跟蹤(tracking object allocation call stack)。 如果分配位置資訊在堆轉儲中不可用. 則必須將此標誌設定為 false. 預設值為 true.>
- -refs false|true 關閉物件引用跟蹤(tracking of references to objects)。 預設值為 true. 預設情況下, 返回的指標是指向其他特定物件的物件,如反向連結或輸入引用(referrers or incoming references), 會統計/計算堆中的所有物件。>
- -port port-number 設定 jhat HTTP server 的埠號. 預設值 7000.>
- -exclude exclude-file 指定物件查詢時需要排除的資料成員列表檔案(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果檔案列列出了 java.lang.String.value , 那麼當從某個特定物件 Object o 計算可達的物件列表時, 引用路徑涉及 java.lang.String.value 的都會被排除。>
- -baseline exclude-file 指定一個基準堆轉儲(baseline heap dump)。 在兩個 heap dumps 中有相同 object ID 的物件會被標記為不是新的(marked as not being new). 其他物件被標記為新的(new). 在比較兩個不同的堆轉儲時很有用.>
- -debug int 設定 debug 級別. 0 表示不輸出除錯資訊。 值越大則表示輸出更詳細的 debug 資訊.>
- -version 啟動後只顯示版本資訊就退出>
- -J< flag > 因為 jhat 命令實際上會啟動一個JVM來執行, 通過 -J 可以在啟動JVM時傳入一些啟動引數. 例如, -J-Xmx512m 則指定執行 jhat 的Java虛擬機器使用的最大堆記憶體為 512 MB. 如果需要使用多個JVM啟動引數,則傳入多個 -Jxxxxxx.
示例
1 2 3 4 5 6 7 8 9 10 |
|
中間的-J-Xmx512m是在dump快照很大的情況下分配512M記憶體去啟動HTTP伺服器,執行完之後就可在瀏覽器開啟Http://localhost:7000進行快照分析 堆快照分析主要在最後面的Heap Histogram裡,裡面根據class列出了dump的時候所有存活物件。
分析同樣一個dump快照,MAT需要的額外記憶體比jhat要小的多的多,所以建議使用MAT來進行分析,當然也看個人偏好。
分析
開啟瀏覽器Http://localhost:7000,該頁面提供了幾個查詢功能可供使用:
1 2 3 4 5 6 7 |
|
一般檢視堆異常情況主要看這個兩個部分: Show instance counts for all classes (excluding platform),平臺外的所有物件資訊。如下圖:
Show heap histogram 以樹狀圖形式展示堆情況。如下圖:
具體排查時需要結合程式碼,觀察是否大量應該被回收的物件在一直被引用或者是否有佔用記憶體特別大的物件無法被回收。
一般情況,會down到客戶端用工具來分析
jstack
jstack用於生成java虛擬機器當前時刻的執行緒快照。執行緒快照是當前java虛擬機器內每一條執行緒正在執行的方法堆疊的集合,生成執行緒快照的主要目的是定位執行緒出現長時間停頓的原因,如執行緒間死鎖、死迴圈、請求外部資源導致的長時間等待等。 執行緒出現停頓的時候通過jstack來檢視各個執行緒的呼叫堆疊,就可以知道沒有響應的執行緒到底在後臺做什麼事情,或者等待什麼資源。 如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,從而可以輕鬆地知道java程式是如何崩潰和在程式何處發生問題。另外,jstack工具還可以附屬到正在執行的java程式中,看到當時執行的java程式的java stack和native stack的資訊, 如果現在執行的java程式呈現hung的狀態,jstack是非常有用的。
命令格式
1 |
|
option引數
- -F : 當正常輸出請求不被響應時,強制輸出執行緒堆疊
- -l : 除堆疊外,顯示關於鎖的附加資訊
- -m : 如果呼叫到本地方法的話,可以顯示C/C++的堆疊
示例
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 |
|
分析
jinfo
jinfo(JVM Configuration info)這個命令作用是實時檢視和調整虛擬機器執行引數。 之前的jps -v口令只能檢視到顯示指定的引數,如果想要檢視未被顯示指定的引數的值就要使用jinfo口令
命令格式
1 |
|
option引數
- -flag : 輸出指定args引數的值
- -flags : 不需要args引數,輸出所有JVM引數的值
- -sysprops : 輸出系統屬性,等同於System.getProperties()
示例
1 2 |
|