天天看點

JVM 虛拟機監控 指令

 jps :列印出所有正在運作 的java程序的相關資訊。

  • jps 列印的資訊包含java程序ID和主類名。-l 列印出主類所在的包名。
JVM 虛拟機監控 指令
$jps -l
320 sun.tools.jps.Jps
118 org.apache.catalina.startup.Bootstrap
           
  • -m 傳給主類的參數 -v 傳給java虛拟機的參數
  • $ jps -mlv
    3210 sun.tools.jps.Jps -mlv -Denv.class.path=/opt/java/jdk1.8.0_172/lib/ -Dapplication.home=/opt/java/jdk1.8.0_172 -Xms8m
               
  • 注意:如果java程序開啟了UsePerfData參數(XX: - UsePerfData),則這些指令則無法探知java程序。
  • jstat : java程序性能相關資訊。具體指令資訊官網: https://docs.oracle.com/en/java/javase/11/tools/jstat.html#GUID-5F72A7F9-5D5A-4486-8201-E1D1BA8ACCB5
    $ jstat -options
    -class  // 列印類加載相關資訊
    -compiler //即時編譯相關資訊
    -gc     // 列印gc相關資訊
    -gccapacity
    -gccause
    -gcmetacapacity
    -gcnew
    -gcnewcapacity
    -gcold
    -gcoldcapacity
    -gcutil
    -printcompilation // 即時編譯先關資訊
               
  • jstat 一般隻會執行一次,按照如下指令可以指定執行次數。
    # Usage: jstat -outputOptions [-t] [-hlines] VMID [interval [count]]
    $ jstat -gc 11978 1s 3
    // KB 機關
    // s0C  代表第一個survivor區總容量,     S1C 代表第二個。
    // S0U  代表第一個survivor區已使用總容量 S1U 代表第二個
    // EC   代表Eden區總容量,就是年輕代      EU 代表已使用容量
    // OC   代表Old區總容量,就是年老代。     OU 代表已使用容量
    // MC   代表中繼資料區總容量就是永久代      MU 代表已使用容量
    // CCSC 代表壓縮類空間容量             CCMU 代表已使用容量
    // YGC  代表年輕代垃圾回收次數    
    // YGCT 代表年輕代垃圾回收時間 
    // FGC  FULL GC  次數,就是指對整個java堆進行垃圾回收,包括年輕代和年老代
    // FGCT  FULL GC 回收時間
    // GCT  總的垃圾回收消耗的時間    
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    512.0  512.0   32.0   0.0   15360.0   8579.4   20480.0    17882.5   19712.0 18988.7 2304.0 2053.9    384    0.757   0      0.000    0.757
    512.0  512.0   32.0   0.0   15360.0   8579.4   20480.0    17882.5   19712.0 18988.7 2304.0 2053.9    384    0.757   0      0.000    0.757
    512.0  512.0   32.0   0.0   15360.0   8579.4   20480.0    17882.5   19712.0 18988.7 2304.0 2053.9    384    0.757   0      0.000    0.757
               
  • -t  一個常用的參數,可以列印出java程序啟動的時間。下面辨別該java程序啟動了1977311.4秒。
    $ jstat -gc -t  11978
    Timestamp        S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    1977311.4        512.0  512.0   32.0   0.0   15360.0  13481.4   20480.0    17882.5   19712.0 18988.7 2304.0 2053.9    384    0.757   0      0.000    0.757
               
  • 這樣就可以判斷出GC 時間占用運作時間比例,超過20%則說明堆壓力較大,超過90%則很可能會發生ooM.多次監控年老代的OU 列則可以看出是否發生記憶體洩漏,即OU不斷在增長。

jmap : 分析堆中對象的狀态 

  • 官方幫助文檔:https://docs.oracle.com/en/java/javase/11/tools/jmap.html#GUID-D2340719-82BA-4077-B0F3-2803269B7F41
  • 子指令:
    -clstats  列印類加載資訊
    
    -finalizerinfo 列印所有待finalizer 的對象
    
    -histo  列印各個類的執行個體數目及占用記憶體,并按照記憶體使用量降序排序。
    
    -histo:live  列印堆中存活對象資訊
    
    -dump  導出java虛拟機記憶體快照,常用也是-dump:live 隻儲存存活對象
               
  • 常用指令 jmap  -dump:live ,format = b, the file = filename. Bin 導出到一個檔案裡進行檢視。
    列印出的資訊一部分:
    
    $ jmap -histo 978
     num        #instances         #bytes  class name (module) 
    
    1543:             1             16  sun.security.x509.RFC822Name
    1544:             1             16  sun.text.normalizer.NormalizerBase$Mode
    1545:             1             16  sun.text.normalizer.NormalizerBase$NFCMode
    1546:             1             16  sun.text.normalizer.NormalizerBase$NFDMode
    1547:             1             16  sun.text.normalizer.NormalizerBase$NFKCMode
               
  • jinfo :用來檢視java程序的參數  

  • 官方文檔:https://docs.oracle.com/en/java/javase/11/tools/jinfo.html#GUID-69246B58-28C4-477D-B375-278F5F9830A5
  • 具體來看就是傳給虛拟機的一些參數,比如 -XX  可以看到自己設定的或者預設設定一些資訊。
    $ jinfo 119
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.172-b11
    Java System Properties:
    
    ...
    ...
    ...
    
    VM Flags:
    Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=482344960 -XX:MaxNewSize=160432128 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=10485760 -XX:OldSize=20971520 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
    
    
               
  • jstack :列印程序的各個線程的資訊,包括線程的鎖。

  • 官方文檔:https://docs.oracle.com/en/java/javase/11/tools/jstack.html#GUID-721096FC-237B-473C-A461-DBBBB79E4F6A
  • 那這裡就可以使用jstack來進行死鎖檢查。
  • 一個死鎖:來自于鄭雨笛老師
    $ jstack 31634
    ...
    
    "Thread-0" #12 prio=5 os_prio=31 cpu=1.32ms elapsed=34.24s tid=0x00007fb08601c800 nid=0x5d03 waiting for monitor entry  [0x000070000bc7e000]
       java.lang.Thread.State: BLOCKED (on object monitor)
     at DeadLock.foo(DeadLock.java:18)
     - waiting to lock <0x000000061ff904c0> (a java.lang.Object)
     - locked <0x000000061ff904b0> (a java.lang.Object)
     at DeadLock$$Lambda$1/0x0000000800060840.run(Unknown Source)
     at java.lang.Thread.run([email protected]/Thread.java:834)
    
    "Thread-1" #13 prio=5 os_prio=31 cpu=1.43ms elapsed=34.24s tid=0x00007fb08601f800 nid=0x5f03 waiting for monitor entry  [0x000070000bd81000]
       java.lang.Thread.State: BLOCKED (on object monitor)
     at DeadLock.bar(DeadLock.java:33)
     - waiting to lock <0x000000061ff904b0> (a java.lang.Object)
     - locked <0x000000061ff904c0> (a java.lang.Object)
     at DeadLock$$Lambda$2/0x0000000800063040.run(Unknown Source)
     at java.lang.Thread.run([email protected]/Thread.java:834)
    
    ...
    
    JNI global refs: 6, weak refs: 0
    
    
    Found one Java-level deadlock:
    =============================
    "Thread-0":
      waiting to lock monitor 0x00007fb083015900 (object 0x000000061ff904c0, a java.lang.Object),
      which is held by "Thread-1"
    "Thread-1":
      waiting to lock monitor 0x00007fb083015800 (object 0x000000061ff904b0, a java.lang.Object),
      which is held by "Thread-0"
    
    Java stack information for the threads listed above:
    ===================================================
    "Thread-0":
     at DeadLock.foo(DeadLock.java:18)
     - waiting to lock <0x000000061ff904c0> (a java.lang.Object)
     - locked <0x000000061ff904b0> (a java.lang.Object)
     at DeadLock$$Lambda$1/0x0000000800060840.run(Unknown Source)
     at java.lang.Thread.run([email protected]/Thread.java:834)
    "Thread-1":
     at DeadLock.bar(DeadLock.java:33)
     - waiting to lock <0x000000061ff904b0> (a java.lang.Object)
     - locked <0x000000061ff904c0> (a java.lang.Object)
     at DeadLock$$Lambda$2/0x0000000800063040.run(Unknown Source)
     at java.lang.Thread.run([email protected]/Thread.java:834)
    
    Found 1 deadlock.
               
  • jcmd :可以實作除了jstat 以外以上所有的指令

  • 官方文檔:https://docs.oracle.com/en/java/javase/11/tools/jcmd.html#GUID-59153599-875E-447D-8D98-0078A5778F05
  • 總結:
    • jps  列印所有java程序Id及一些相關的資訊,比如主類,主類所在的包等
    • jstat  列印java程序的的類加載及gc資訊
    • jmap  列印對象的資訊,比如類的執行個體數目,類所有執行個體占用記憶體大小。常用來檢視占用記憶體過大的對象。
    • jinfo 列印java程序的配置參數,常用的-XX 及各種設定的參數。也可以修改參數值
    • jstack  列印java程序的各個線程資訊,及線程的鎖。喲哪裡檢測死鎖
    • jcmd  實作出jstat以外的上述功能

繼續閱讀