概述
在JDK1.7以后,新增了一個(gè)命令行工具 jcmd。他是一個(gè)多功能的工具,可以用它來(lái)導(dǎo)出堆、查看Java進(jìn)程、導(dǎo)出線(xiàn)程信息、執(zhí)行GC、還可以進(jìn)行采樣分析(jmc 工具的飛行記錄器)。
命令格式
jcmd <pid | main class> <command ... | PerfCounter.print | -f file>
jcmd -l
jcmd -h
描述
pid:接收診斷命令請(qǐng)求的進(jìn)程ID。
main class :接收診斷命令請(qǐng)求的進(jìn)程的main類(lèi)。匹配進(jìn)程時(shí),main類(lèi)名稱(chēng)中包含指定子字符串的任何進(jìn)程均是匹配的。如果多個(gè)正在運(yùn)行的Java進(jìn)程共享同一個(gè)main類(lèi),診斷命令請(qǐng)求將會(huì)發(fā)送到所有的這些進(jìn)程中。-
command:接收診斷命令請(qǐng)求的進(jìn)程的main類(lèi)。匹配進(jìn)程時(shí),main類(lèi)名稱(chēng)中包含指定子字符串的任何進(jìn)程均是匹配的。如果多個(gè)正在運(yùn)行的Java進(jìn)程共享同一個(gè)main類(lèi),診斷命令請(qǐng)求將會(huì)發(fā)送到所有的這些進(jìn)程中。
注意: 如果任何參數(shù)含有空格,你必須使用英文的單引號(hào)或雙引號(hào)將其包圍起來(lái)。 此外,你必須使用轉(zhuǎn)義字符來(lái)轉(zhuǎn)移參數(shù)中的單引號(hào)或雙引號(hào),以阻止操作系統(tǒng)shell處理這些引用標(biāo)記。當(dāng)然,你也可以在參數(shù)兩側(cè)加上單引號(hào),然后在參數(shù)內(nèi)使用雙引號(hào)(或者,在參數(shù)兩側(cè)加上雙引號(hào),在參數(shù)中使用單引號(hào))。
Perfcounter.print:打印目標(biāo)Java進(jìn)程上可用的性能計(jì)數(shù)器。性能計(jì)數(shù)器的列表可能會(huì)隨著Java進(jìn)程的不同而產(chǎn)生變化。
-f file:從文件file中讀取命令,然后在目標(biāo)Java進(jìn)程上調(diào)用這些命令。在file中,每個(gè)命令必須寫(xiě)在單獨(dú)的一行。以"#"開(kāi)頭的行會(huì)被忽略。當(dāng)所有行的命令被調(diào)用完畢后,或者讀取到含有stop關(guān)鍵字的命令,將會(huì)終止對(duì)file的處理。
-l:查看所有的進(jìn)程列表信息。
-h:查看幫助信息。(同 -help)
查看進(jìn)程 jcmd -l
命令:jcmd -l
描述:查看 當(dāng)前機(jī)器上所有的 jvm 進(jìn)程信息
jcmd
jcmd -l
jps
這三個(gè)命令的效果是一樣的
查看性能統(tǒng)計(jì)
命令:jcmd pid PerfCounter.print
描述:查看指定進(jìn)程的性能統(tǒng)計(jì)信息。
C:\Windows\system32>jcmd 9592 PerfCounter.print
9592:
java.ci.totalTime=16704
java.cls.loadedClasses=438
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=0
java.property.java.class.path="D:\work\git\test\target\classes"
java.property.java.endorsed.dirs="D:\Program Files\Java\jre1.8.0_91\lib\endorsed"
java.property.java.ext.dirs="D:\Program Files\Java\jre1.8.0_91\lib\ext;C:\Windows\Sun\Java\lib\ext"
java.property.java.home="D:\Program Files\Java\jre1.8.0_91"
...
列出當(dāng)前運(yùn)行的 java 進(jìn)程可以執(zhí)行的操作
命令:jcmd PID help
C:\Windows\system32>jcmd 9592 help
9592:
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
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help
查看具體命令的選項(xiàng)
如果想查看命令的選項(xiàng),比如想查看 JFR.dump 命令選項(xiàng),可以通過(guò)如下命令:
jcmd 11772 help JFR.dump

1.JRF 相關(guān)命令
JRF 功能跟 jmc.exe 工具的飛行記錄器的功能一樣的。
要使用 JRF 相關(guān)的功能,必須使用 VM.unlock_commercial_features 參數(shù)取消鎖定商業(yè)功能 。


啟動(dòng)JFR
執(zhí)行命令:jcmd $PID JFR.start name=abc,duration=120sDump JFR
等待至少duration(本文設(shè)定120s)后,執(zhí)行命令:jcmd PID JFR.dump name=abc,duration=120s filename=abc.jfr(注意,文件名必須為.jfr后綴)檢查JFR狀態(tài)
執(zhí)行命令:jcmd $PID JFR.check name=abc,duration=120s停止JFR
執(zhí)行命令:jcmd $PID JFR.stop name=abc,duration=120sJMC分析
切回開(kāi)發(fā)機(jī)器,下載步驟3中生成的abc.jfr,打開(kāi)jmc,導(dǎo)入abc.jfr即可進(jìn)行可視化分析
VM.uptime
命令:jcmd PID VM.uptime
描述:查看 JVM 的啟動(dòng)時(shí)長(zhǎng):

GC.class_histogram
命令:jcmd PID GC.class_histogram
描述:查看系統(tǒng)中類(lèi)統(tǒng)計(jì)信息

這里和jmap -histo pid的效果是一樣的
這個(gè)可以查看每個(gè)類(lèi)的實(shí)例數(shù)量和占用空間大小。
Thread.print
命令:jcmd PID Thread.print
描述:查看線(xiàn)程堆棧信息。

該命令同 jstack 命令。
GC.heap_dump
命令:jcmd PID GC.heap_dump FILE_NAME
描述:查看 JVM 的Heap Dump
C:\Users\jjs>jcmd 10576 GC.heap_dump d:\dump.hprof
10576:
Heap dump file created
跟 jmap命令:jmap -dump:format=b,file=heapdump.phrof pid 效果一樣。
導(dǎo)出的 dump 文件,可以使用MAT 或者 Visual VM 等工具進(jìn)行分析。
注意:如果只指定文件名,默認(rèn)會(huì)生成在啟動(dòng) JVM 的目錄里。
VM.system_properties
命令:jcmd PID VM.system_properties
描述:查看 JVM 的屬性信息
C:\Users\jjs>jcmd 10576 VM.system_properties
10576:
#Wed Jan 31 22:30:20 CST 2018
java.vendor=Oracle Corporation
osgi.bundles.defaultStartLevel=4
......
os.version=10.0
osgi.arch=x86_64
path.separator=;
java.vm.version=25.91-b15
org.osgi.supports.framework.fragment=true
user.variant=
osgi.framework.shape=jar
java.awt.printerjob=sun.awt.windows.WPrinterJob
osgi.instance.area.default=file\:/C\:/Users/jjs/eclipse-workspace/
sun.io.unicode.encoding=UnicodeLittle
org.osgi.framework.version=1.8.0
......
VM.flags
命令:jcmd PID VM.flags
描述:查看 JVM 的啟動(dòng)參數(shù)
C:\Users\jjs>jcmd 10576 VM.flags
10576:
-XX:CICompilerCount=3 -XX:ConcGCThreads=1
-XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=268435456
-XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824
-XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576
-XX:+UseCompressedClassPointers -XX:+UseCompressedOops
-XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC
-XX:-UseLargePagesIndividualAllocation -XX:+UseStringDeduplication
VM.command_line
命令:jcmd PID VM.command_line
描述:查看 JVM 的啟動(dòng)命令行
C:\Users\jjs>jcmd 10576 VM.command_line
10576:
VM Arguments:
jvm_args: -Dosgi.requiredJavaVersion=1.8
-Dosgi.instance.area.default=@user.home/eclipse-workspace
-XX:+UseG1GC -XX:+UseStringDeduplication
-Dosgi.requiredJavaVersion=1.8 -Xms256m -Xmx1024m
java_command: <unknown>
java_class_path (initial): D:\tool\...\org.eclipse.equinox.launcher.jar
GC.run_finalization
命令:jcmd PID GC.run_finalization
描述: 對(duì) JVM 執(zhí)行 java.lang.System.runFinalization()
C:\Users\jjs>jcmd 10576 GC.run_finalization
10576:
Command executed successfully
執(zhí)行一次finalization操作,相當(dāng)于執(zhí)行java.lang.System.runFinalization()
GC.run
命令:jcmd PID GC.run
描述:對(duì) JVM 執(zhí)行 java.lang.System.gc()
C:\Users\jjs>jcmd 10576 GC.run
10576:
Command executed successfully
告訴垃圾收集器打算進(jìn)行垃圾收集,而垃圾收集器進(jìn)不進(jìn)行收集是不確定的。
PerfCounter.print
命令:jcmd PID PerfCounter.print
描述:查看 JVM 性能相關(guān)的參數(shù)
C:\Users\jjs>jcmd 10576 PerfCounter.print
10576:
java.ci.totalTime=93024843
java.cls.loadedClasses=18042
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=3
......
VM.version
命令:jcmd PID VM.version
描述:查看目標(biāo)jvm進(jìn)程的版本信息
C:\Users\jjs>jcmd 10576 VM.version
10576:
Java HotSpot(TM) 64-Bit Server VM version 25.91-b15
JDK 8.0_91