文章目錄
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 相關命令
-
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 ......
-
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
-
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 直接內存,此處主要介紹可用於追蹤內存泄露情況的命令
jcmd 22852 VM.native_memory baseline
以 Java 進程當前內存使用情況創建一條基線jcmd 22852 VM.native_memory summary.diff scale=KB
運行一段時間後使用summary.diff
來查看跟baseline
對比的統計信息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)