JVM 命令指北(6)-jcmd 命令

1. 功能介紹

JDK1.7以後新增了一個命令行工具 jcmd,使用它可以查看堆信息、查看Java進程、導出線程信息、執行GC,還可以進行採樣分析(類似 jmc 工具的飛行記錄器),可以把它看作 jps/jmap/jstack等工具的集合

2. jcmd 命令詳解

2.1 命令格式

在終端界面使用 jcmd -h 可以方便地獲得該命令幫助文檔,其命令格式如下

命令格式 說明
jcmd < pid | main class> <command …| PerfCounter.print | -f file> 最常用的命令格式,有多個參數
jcmd -l 相當於 jps 命令
  • 常用的 jcmd 命令各參數含義如下
    參數 含義
    pid 接收診斷命令請求的進程 ID
    main class 接收診斷命令請求的進程的 main 類。匹配進程時,main類名稱中包含指定子字符串的任何進程均是匹配的。如果多個正在運行的Java進程共享同一個main類,診斷命令請求將會發送到所有的這些進程中
    command 必須是有效的 jcmd 命令,如果指定 pid 爲 0,則該命令會發送給所有的 Java 進程。注意,如果參數含有空格,必須使用英文的單引號或雙引號參數包圍起來,另外須使用轉義字符\來轉義參數中的單引號或雙引號,以阻止操作系統 shell 處理這些引用標記
    Perfcounter.print 打印目標 Java 進程上性能統計信息,這個列表可能會隨着 Java 進程的不同而產生變化
    -f file 從文件 file 中讀取命令,然後在目標 Java 進程上調用這些命令。在 file 中每個命令必須在單獨的一行,以"#"開頭的行會被忽略。當所有行的命令被調用完畢或者讀取到含有 stop 關鍵字的命令,處理終止

2.2 常用 command 參數詳解

使用 jcmd <pid> help 命令可以查看對於指定 PID 可以調用的 command 參數,常規打印如下。可以看到大致包含了 JFR GC VM 三個大類

// 執行的命令
jcmd 1715 help
// 對進程 1715 可用的 command 參數
1715:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help

2.2.1 GC 前綴

GC前綴的 command 參數主要用於查看堆內垃圾收集相關的信息,參數表如下

參數 功能
GC.rotate_log gc 日誌輪換命令,使用該命令後強制創建一個新的 gc 日誌文件
GC.class_stats 打印被加載類的更詳細信息,需啓用參數 -XX:+UnlockDiagnosticVMOptions
GC.class_histogram 查看堆中每個類的實例數量和佔用內存空間大小
GC.heap_dump 導出 JVM 的 Heap Dump,如果只指定文件名,默認會生成在啓動 JVM 的目錄裏
GC.finalizer_info 等待回收的對象信息
GC.heap_info 打印堆的簡要信息,包括使用的GC算法、堆配置信息
Thread.print 打印線程棧信息,類似 jstack -l
GC.run_finalization 執行 java.lang.System.runFinalization(),強制調用已經失去引用的對象的 finalize 方法
GC.run 執行 java.lang.System.gc(),JVM會在合適的時機進行 Full GC

2.2.2 VM 前綴

VM前綴的 command 參數主要用於查看虛擬機相關的信息,參數表及功能如下

參數 功能
VM.native_memory 打印整個 Java 進程內存佔用情況,需啓用參數-XX:NativeMemoryTracking=[summary | detail]
VM.check_commercial_features 查看商業功能,使用前需使用 VM.unlock_commercial_features 取消鎖定商業功能
VM.classloader_stats 打印類加載器信息
VM.uptime 查看虛擬機啓動時間
VM.dynlibs 打印動態連接庫信息
VM.flags 查看虛擬機啓動參數
VM.system_properties 查看 JVM 的屬性信息
VM.command_line 查看啓動命令
VM.version 查看虛擬機版本

2.2.4 JFR 前綴

JRF 功能跟 jmc工具的飛行記錄器的功能一樣的,使用相關功能必須使用 VM.unlock_commercial_features 參數取消鎖定商業功能。執行 JFR 命令dump 出 jfr 文件後,需要導入到 jmc 工具中做可視化分析

參數 功能
JFR.start name=hello duration=120s 啓動 JFR
JFR.check name=hello duration=120s 檢查 JFR 狀態
JFR.stop name=hello duration=120s 停止 JFR
JFR.dump name=hello duration=120s filename=hello.jfr(文件名必須爲.jfr後綴) 等待至少 duration(此處設定120s)後,執行命令 dump 出文件

3. 使用示例

3.1 GC 相關命令

  1. jcmd 22852 GC.class_stats | more 打印的內容如下,比較關鍵的信息有加載類的名稱(ClassName)、每個類所佔據的字節(KlassBytes)、每個類的實例所佔據的字節(InstBytes)、每個類中方法的數量(MethodCount)、字節碼所佔據的空間(ByteCodes))

    22852:
    Index Super InstBytes KlassBytes annotations    CpAll MethodCount Bytecodes MethodAll    ROAll    RWAll    Total ClassName
     1    -1   8159824        480           0        0           0         0         0       24      584      608 [C
     2    16   2508576        568           0     1344           8       223      1744     1024     2952     3976 java.util.concurrent.ConcurrentHashMap$Node
     3    -1   2266352        480           0        0           0         0         0       24      584      608 [B
     4  8253   2177296       1112           0     5512          40       847     20528     4224    23608    27832 java.lang.reflect.Method
     5    16   2023608        624           0     8712          94      4623     52496    12136    50776    62912 java.lang.String
     6    16   1595480        648           0    19384         130      4973     68112    16552    73368    89920 java.lang.Class
     7    -1   1147856        480           0        0           0         0         0       24      584      608 [Ljava.lang.Object;
     8    16    958656        632           0     2280          10       248      4760     1640     6400     8040 org.aspectj.weaver.reflect.ShadowMatchImpl
     9    -1    912752        480           0        0           0         0         0       24      584      608 [I
    10    13    819080        560           0      384           1        10       496      232     1432     1664 java.util.LinkedHashMap$Entry
    ......
    
  2. jcmd 22852 GC.heap_info 打印堆內存使用信息

    22852:
    // G1 收集器,堆使用情況
    garbage-first heap   total 106496K, used 31763K [0x00000000f8000000, 0x00000000f8100340, 0x0000000100000000)
    // G1 region 的大小,年輕代有 1個 region,survivors 0 個 region
    region size 1024K, 1 young (1024K), 0 survivors (0K)
    // 元空間使用情況
    Metaspace       used 73058K, capacity 75244K, committed 75976K, reserved 1116160K
    class space    used 9071K, capacity 9493K, committed 9672K, reserved 1048576K
    
  3. jcmd 22852 Thread.print | less 打印線程棧,與 jstack -l 22852效果相同

    22852:
    2020-04-08 18:10:06
    Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):
    
    "logback-8" #78 daemon prio=5 os_prio=0 tid=0x00007f4f54001000 nid=0x63f2 waiting on condition [0x00007f4f993e8000]
    java.lang.Thread.State: WAITING (parking)
         at sun.misc.Unsafe.park(Native Method)
         - parking to wait for  <0x00000000f840cd38> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
         at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
         at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
         at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
         at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
         at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
         at java.lang.Thread.run(Thread.java:748)
         
         .......
    

3.2 VM 相關命令

VM 相關的命令中最重要的就是 VM.native_memory,該命令主要用於查看整個 Java 進程的內存佔用,必要時還可以進行追蹤檢測。jcm < pid > VM.native_memory scale=MB 的輸出可參考JVM 直接內存此處主要介紹可用於追蹤內存泄露情況的命令

  1. jcmd 22852 VM.native_memory baseline 以 Java 進程當前內存使用情況創建一條基線
  2. jcmd 22852 VM.native_memory summary.diff scale=KB 運行一段時間後使用 summary.diff 來查看跟baseline對比的統計信息
  3. jcmd 22852 VM.native_memory shutdown可以用於關閉 NMT,但是關閉之後沒有對應 jcmd 命令來開啓
    22852:
    
    Native Memory Tracking:
    // 統計情況看,保留的內存增加了 37K,實際使用的內存增加了 293K 
    Total: reserved=1642215KB +37KB, committed=349111KB +293KB
    
    -                 Java Heap (reserved=131072KB, committed=106496KB)
                             (mmap: reserved=131072KB, committed=106496KB)
    
    -                     Class (reserved=1118433KB, committed=78505KB +256KB)
                             (classes #13496)
                             (malloc=2273KB #18090 +10)
                             (mmap: reserved=1116160KB, committed=76232KB +256KB)
    
    -                    Thread (reserved=55638KB, committed=55638KB)
                             (thread #55)
                             (stack: reserved=55404KB, committed=55404KB)
                             (malloc=170KB #282)
                             (arena=63KB #104)
    
    -                      Code (reserved=253929KB +34KB, committed=26497KB +34KB)
                             (malloc=4329KB +34KB #6590 +52)
                             (mmap: reserved=249600KB, committed=22168KB)
    
    -                        GC (reserved=55718KB +1KB, committed=54806KB +1KB)
                             (malloc=18086KB +1KB #12432 +49)
                             (mmap: reserved=37632KB, committed=36720KB)
    
    -                  Compiler (reserved=165KB, committed=165KB)
                             (malloc=35KB #530)
                             (arena=131KB #7)
    
    -                  Internal (reserved=3285KB, committed=3285KB)
                             (malloc=3253KB #19786 +2)
                             (mmap: reserved=32KB, committed=32KB)
    
    -                    Symbol (reserved=19850KB, committed=19850KB)
                             (malloc=17029KB #176152)
                             (arena=2821KB #1)
    
    -    Native Memory Tracking (reserved=3671KB +2KB, committed=3671KB +2KB)
                             (malloc=12KB #137)
                             (tracking overhead=3660KB +2KB)
    
    -               Arena Chunk (reserved=198KB, committed=198KB)
                             (malloc=198KB)
    
    -                   Unknown (reserved=256KB, committed=0KB)
                             (mmap: reserved=256KB, committed=0KB)
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章