1. 程式人生 > >JVM監控和調優常用命令工具總結

JVM監控和調優常用命令工具總結

JVM監控和調優

在Java應用和服務出現莫名的卡頓、CPU飆升等問題時總是要分析一下對應程序的JVM狀態以定位問題和解決問題並作出相應的優化,在這過程中Java自帶的一些狀態監控命令和圖形化工具就非常方便了。本文總結了最常用的命令列工具及其常用引數解釋,圖形化監控工具的用法,僅供參考。

jps

Java版的ps命令,檢視java程序及其相關的資訊,如果你想找到一個java程序的pid,那可以用jps命令替代linux中的ps命令了,簡單而方便。

命令格式:

jps [options] [hostid]

options引數解釋:

  • -l : 輸出主類全名或jar路徑
  • -q : 只輸出LVMID
  • -m : 輸出JVM啟動時傳遞給main()的引數
  • -v : 輸出JVM啟動時顯示指定的JVM引數

最常用示例:

jps -l 輸出jar包路徑,類全名
jps -m 輸出main引數
jps -v 輸出JVM引數

jinfo

jinfo是用來檢視JVM引數和動態修改部分JVM引數的命令

命令格式:

jinfo [option] <pid>

options引數解釋:

  • -flag <name> 列印指定名稱的引數
  • -flag [+|-]<name> 開啟或關閉引數
  • -flag <name>=<value> 設定引數
  • -flags 列印所有引數
  • -sysprops 列印系統配置
  • <no option> 列印上面兩個選項

最常用示例:

其中11666為pid

檢視JVM引數和系統配置

jinfo 11666
jinfo -flags 11666
jinfo -sysprops 11666

檢視列印GC日誌引數

jinfo -flag PrintGC 11666
jinfo -flag PrintGCDetails 11666

開啟GC日誌引數

jinfo -flag +PrintGC 11666
jinfo -flag +PrintGCDetails 11666

關閉GC日誌引數

jinfo -flag -PrintGC 11666
jinfo -flag -PrintGCDetails 11666

還可以使用下面的命令檢視那些引數可以使用jinfo命令來管理:

java -XX:+PrintFlagsFinal -version | grep manageable

常用JVM引數:

-Xms:初始堆大小,預設為實體記憶體的1/64(<1GB);預設(MinHeapFreeRatio引數可以調整)空餘堆記憶體小於40%時,JVM就會增大堆直到-Xmx的最大限制 -Xmx:最大堆大小,預設(MaxHeapFreeRatio引數可以調整)空餘堆記憶體大於70%時,JVM會減少堆直到 -Xms的最小限制 -Xmn:新生代的記憶體空間大小,注意:此處的大小是(eden+ 2 survivor space)。與jmap -heap中顯示的New gen是不同的。整個堆大小=新生代大小 + 老生代大小 + 永久代大小。       在保證堆大小不變的情況下,增大新生代後,將會減小老生代大小。此值對系統性能影響較大,Sun官方推薦配置為整個堆的3/8。 -XX:SurvivorRatio:新生代中Eden區域與Survivor區域的容量比值,預設值為8。兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區佔整個年輕代的1/10。 -Xss:每個執行緒的堆疊大小。JDK5.0以後每個執行緒堆疊大小為1M,以前每個執行緒堆疊大小為256K。應根據應用的執行緒所需記憶體大小進行適當調整。在相同實體記憶體下,       減小這個值能生成更多的執行緒。但是作業系統對一個程序內的執行緒數還是有限制的,不能無限生成,經驗值在3000~5000左右。一般小的應用, 如果棧不是很深, 應該是128k夠用的,       大的應用建議使用256k。這個選項對效能影響比較大,需要嚴格的測試。和threadstacksize選項解釋很類似,官方文件似乎沒有解釋,       在論壇中有這樣一句話:"-Xss  is  translated  in  a VM flag named ThreadStackSize”一般設定這個值就可以了。 -XX:PermSize:設定永久代(perm gen)初始值。預設值為實體記憶體的1/64。 -XX:MaxPermSize:設定持久代最大值。實體記憶體的1/4。

jstat

jstat命令是使用頻率比較高的命令,主要用來檢視JVM執行時的狀態資訊,包括記憶體狀態、垃圾回收等。

命令格式:

jstat [option] LVMID [interval] [count]

其中LVMID是程序id,interval是列印間隔時間(毫秒),count是列印次數(預設一直列印)

option引數解釋:

  • -class class loader的行為統計
  • -compiler HotSpt JIT編譯器行為統計
  • -gc 垃圾回收堆的行為統計
  • -gccapacity 各個垃圾回收代容量(young,old,perm)和他們相應的空間統計
  • -gcutil 垃圾回收統計概述
  • -gccause 垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因
  • -gcnew 新生代行為統計
  • -gcnewcapacity 新生代與其相應的記憶體空間的統計
  • -gcold 年老代和永生代行為統計
  • -gcoldcapacity 年老代行為統計
  • -gcpermcapacity 永生代行為統計
  • -printcompilation HotSpot編譯方法統計

常用示例及列印欄位解釋:

jstat -gcutil 11666 1000 3

11666為pid,每隔1000毫秒列印一次,列印3次

輸出:

S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT

6.17   0.00   6.39  33.72  93.42  90.57    976   57.014    68   53.153  110.168

6.17   0.00   6.39  33.72  93.42  90.57    976   57.014    68   53.153  110.168

6.17   0.00   6.39  33.72  93.42  90.57    976   57.014    68   53.153  110.168

欄位解釋:

  • S0 survivor0使用百分比
  • S1 survivor1使用百分比
  • E Eden區使用百分比
  • O 老年代使用百分比
  • M 元資料區使用百分比
  • CCS 壓縮使用百分比
  • YGC 年輕代垃圾回收次數
  • YGCT 年輕代垃圾回收消耗時間
  • FGC 老年代垃圾回收次數
  • FGCT 老年代垃圾回收消耗時間
  • GCT 垃圾回收消耗總時間
jstat -gc 11666 1000 3

-gc和-gcutil引數類似,只不過輸出欄位不是百分比,而是實際的值。

輸出:

S0C        S1C        S0U  S1U     EC           EU           OC             OU            MC          MU         CCSC      CCSU       YGC  YGCT    FGC   FGCT    GCT

25600.0 25600.0  0.0   1450.0 204800.0 97460.7   512000.0   172668.8  345736.0 322997.7 48812.0 44209.0    977   57.040  68     53.153  110.193

25600.0 25600.0  0.0   1450.0 204800.0 97460.7   512000.0   172668.8  345736.0 322997.7 48812.0 44209.0    977   57.040  68     53.153  110.193

25600.0 25600.0  0.0   1450.0 204800.0 97460.7   512000.0   172668.8  345736.0 322997.7 48812.0 44209.0    977   57.040  68     53.153  110.193

欄位解釋:

  • S0C survivor0大小
  • S1C survivor1大小
  • S0U survivor0已使用大小
  • S1U survivor1已使用大小
  • EC Eden區大小
  • EU Eden區已使用大小
  • OC 老年代大小
  • OU 老年代已使用大小
  • MC 方法區大小
  • MU 方法區已使用大小
  • CCSC 壓縮類空間大小
  • CCSU 壓縮類空間已使用大小
  • YGC 年輕代垃圾回收次數
  • YGCT 年輕代垃圾回收消耗時間
  • FGC 老年代垃圾回收次數
  • FGCT 老年代垃圾回收消耗時間
  • GCT 垃圾回收消耗總時間

jstack

jstack是用來檢視JVM執行緒快照的命令,執行緒快照是當前JVM執行緒正在執行的方法堆疊集合。使用jstack命令可以定位執行緒出現長時間卡頓的原因,例如死鎖,死迴圈等。jstack還可以檢視程式崩潰時生成的core檔案中的stack資訊。

命令格式:

jstack [-l] <pid> (連線執行中的程序)
jstack -F [-m] [-l] <pid> (連線掛起的程序)
jstack [-m] [-l] <executable> <core> (連線core檔案)
jstack [-m] [-l] [[email protected]]<remote server IP or hostname> (連線遠端debug伺服器)

option引數解釋:

  • -F 當使用jstack <pid>無響應時,強制輸出執行緒堆疊。
  • -m 同時輸出java和本地堆疊(混合模式)
  • -l 額外顯示鎖資訊

常用示例:

jstack -l 11666 | more

輸出資訊:

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode):

"Attach Listener" #25525 daemon prio=9 os_prio=0 tid=0x00007fd374002000 nid=0x70e8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None
......

具體的輸出解釋比較多,後續會有一篇部落格來解釋。現在想要學習的話請參考這篇部落格

jmap

jmap是用來生成堆dump檔案和檢視堆相關的各類資訊的命令,例如檢視finalize執行佇列,heap的詳細資訊和使用情況。

命令格式:

jmap [option] <pid> (連線正在執行的程序)
jmap [option] <executable <core> (連線一個core檔案)
jmap [option] [[email protected]]<remote server IP or hostname> (連結遠端伺服器)

option引數解釋:

  • <none> to print same info as Solaris pmap
  • -heap 列印java heap摘要
  • -histo[:live] 列印堆中的java物件統計資訊
  • -clstats 列印類載入器統計資訊
  • -finalizerinfo 列印在f-queue中等待執行finalizer方法的物件
  • -dump:<dump-options> 生成java堆的dump檔案

      dump-options:

      live 只轉儲存活的物件,如果沒有指定則轉儲所有物件

      format=b 二進位制格式

      file=<file> 轉儲檔案到 <file>

  • -F 強制選項

 常用示例:

jmap -dump:live,format=b,file=dump.hprof 11666

輸出:

Dumping heap to /dump.hprof ...
Heap dump file created

這個命令是要把java堆中的存活物件資訊轉儲到dump.hprof檔案

jmap -finalizerinfo 11666

輸出:

Attaching to process ID 11666, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01
Number of objects pending for finalization: 0

輸出結果的含義為當前沒有在等待執行finalizer方法的物件

jmap -heap 11666

輸出堆的詳細資訊

輸出:

Attaching to process ID 11666, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration: //堆記憶體初始化配置
   MinHeapFreeRatio         = 0 //對應jvm啟動引數-XX:MinHeapFreeRatio設定JVM堆最小空閒比率(default 40)
   MaxHeapFreeRatio         = 100 //對應jvm啟動引數 -XX:MaxHeapFreeRatio設定JVM堆最大空閒比率(default 70)
   MaxHeapSize              = 1073741824 (1024.0MB) //對應jvm啟動引數-XX:MaxHeapSize=設定JVM堆的最大大小
   NewSize                  = 22020096 (21.0MB) //對應jvm啟動引數-XX:NewSize=設定JVM堆的新生代的預設大小
   MaxNewSize               = 357564416 (341.0MB) //對應jvm啟動引數-XX:MaxNewSize=設定JVM堆的新生代的最大大小
   OldSize                  = 45088768 (43.0MB) //對應jvm啟動引數-XX:OldSize=<value>:設定JVM堆的老年代的大小
   NewRatio                 = 2 //對應jvm啟動引數-XX:NewRatio=:新生代和老生代的大小比率
   SurvivorRatio            = 8 //對應jvm啟動引數-XX:SurvivorRatio=設定新生代中Eden區與Survivor區的大小比值
   MetaspaceSize            = 21807104 (20.796875MB) // 元資料區大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //類壓縮空間大小
   MaxMetaspaceSize         = 17592186044415 MB //元資料區最大大小
   G1HeapRegionSize         = 0 (0.0MB) //G1垃圾收集器每個Region大小

Heap Usage: //堆記憶體使用情況
PS Young Generation 
Eden Space: //Eden區記憶體分佈
   capacity = 17825792 (17.0MB) //Eden區總容量
   used     = 12704088 (12.115562438964844MB) //Eden區已使用
   free     = 5121704 (4.884437561035156MB) //Eden區剩餘容量
   71.26801434685203% used //Eden區使用比率
From Space: //其中一個Survivor區的記憶體分佈
   capacity = 2097152 (2.0MB)
   used     = 1703936 (1.625MB)
   free     = 393216 (0.375MB)
   81.25% used
To Space: //另一個Survivor區的記憶體分佈
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 52428800 (50.0MB) //老年代容量
   used     = 28325712 (27.013504028320312MB) //老年代已使用
   free     = 24103088 (22.986495971679688MB) //老年代空閒
   54.027008056640625% used //老年代使用比率

15884 interned Strings occupying 2075304 bytes.
jmap -histo:live 11666 | more

輸出存活物件統計資訊

輸出:

num     #instances         #bytes  class name
----------------------------------------------
1:         46608        1111232  java.lang.String
2:          6919         734516  java.lang.Class
3:          4787         536164  java.net.SocksSocketImpl
4:         15935         497100  java.util.concurrent.ConcurrentHashMap$Node
5:         28561         436016  java.lang.Object

jhat

jhat是用來分析jmap生成dump檔案的命令,jhat內建了應用伺服器,可以通過網頁檢視dump檔案分析結果,jhat一般是用在離線分析上。

命令格式:

jhat [option] [dumpfile]

option引數解釋:

  • -stack false: 關閉物件分配呼叫堆疊的跟蹤
  • -refs false: 關閉物件引用的跟蹤
  • -port <port>: HTTP伺服器埠,預設是7000
  • -debug <int>: debug級別

   0: 無debug輸出

 

   1: Debug hprof file parsing

 

   2: Debug hprof file parsing, no server

 

  • -version 分析報告版本

常用示例:

jhat dump.hprof

jconsole, jvisualvm

除了以上所述的常用命令列工具之外還有圖形化工具,使用上比較簡單。在命令列下執行jconsole和jvisualvm即可。具體的用法,自己去點一點就瞭解了。

jconsole:

 

 

jvisualvm: