jcmd 是 JDK 自带的一个命令行工具,用于向正在运行的 Java 进程发送诊断命令。通过 jcmd 命令,可以获取 Java 进程的信息、执行诊断操作,以及触发一些特定的操作,例如线程转储、GC 操作、JVM 性能监控等。
jcmd <pid | main class> <command ...|PerfCounter.print|-f file> jcmd -l jcmd -h
<pid> 是目标 Java 进程的进程 ID,如果 pid 为 0,命令将发送给所有 Java 进程。
<main class> 是目标 Java 进程的主类名。
<command> 是要执行的诊断命令,例如 Thread.print、GC.run 等,必须是所选 jvm 的有效 jcmd 命令。可以使用“help”命令可查看哪些命令可用。
<command options> 是命令的选项参数。
PerfCounter.print 显示该进程暴露的计数器:
-f 从文件中读取并执行命令
-l 列出本地机器上的 JVM 进程
-h 帮助信息
注意:如果未给出任何选项,将列出 Java 进程(与 -p)相同。
以下是 jcmd 命令的一些常见用法和常用命令:
(1)列出正在运行的 Java 进程的 ID,例如:
C:\Program Files\Java\jdk1.8.0_171\bin> jcmd -l 22848 sun.tools.jcmd.JCmd -l 11848 1768 org.jetbrains.jps.cmdline.Launcher ... 23176 org.jetbrains.jps.cmdline.Launcher ... 24008 28456 org.jetbrains.jps.cmdline.Launcher ... 24412 com.hxstrive.demo202312.Demo20231207193016 5644 org.jetbrains.jps.cmdline.Launcher ...
(2)列出指定 Java 进程的诊断命令列表,例如:
C:\Program Files\Java\jdk1.8.0_171\bin> jcmd 24412 help 24412: 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 For more information about a specific command use 'help <command>'
(3)执行线程转储(类似于 jstack 命令),例如:
C:\Program Files\Java\jdk1.8.0_171\bin>jcmd 24412 Thread.print 24412: 2023-12-07 19:34:18 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode): "Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001ebdf000 nid=0x11d4 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001eb39800 nid=0x4f68 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001eb33800 nid=0xea8 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001eb2f800 nid=0x3cb0 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001eb2e800 nid=0x2ff4 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001eb16800 nid=0x7104 runnable [0x000000001f23e000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) - locked <0x000000076c503340> (a java.io.InputStreamReader) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) - locked <0x000000076c503340> (a java.io.InputStreamReader) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:53) "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001ea7b800 nid=0x2870 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001ead0800 nid=0x559c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001ea60800 nid=0xbd8 in Object.wait() [0x000000001ef3e000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076c388ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x000000076c388ed0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212) "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000000330a000 nid=0x28fc in Object.wait() [0x000000001ea3f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076c386bf8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x000000076c386bf8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "main" #1 prio=5 os_prio=0 tid=0x0000000003214000 nid=0x2864 waiting on condition [0x0000000002f8f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at com.huangxin.demo202312.Demo20231207193016.main(Demo20231207193016.java:12) "VM Thread" os_prio=2 tid=0x000000001cb69000 nid=0x2fbc runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000003229000 nid=0x4b68 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000000000322b000 nid=0x417c runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000322c800 nid=0x28b0 runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000322e000 nid=0x272c runnable "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000003231000 nid=0x94c runnable "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000003232800 nid=0x1020 runnable "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000003235800 nid=0x72e4 runnable "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000003236800 nid=0x370 runnable "VM Periodic Task Thread" os_prio=2 tid=0x000000001ec40000 nid=0x1d10 waiting on condition JNI global references: 12
(4)执行 GC 操作(类似于 jmap -histo 命令),例如:
C:\Program Files\Java\jdk1.8.0_171\bin> jcmd 24412 GC.run 24412: Command executed successfully
(5)执行 JFR(Java Flight Recorder)相关操作,例如:
C:\Program Files\Java\jdk1.8.0_171\bin> jcmd 24412 JFR.start 24412: Java Flight Recorder not enabled. Use VM.unlock_commercial_features to enable. C:\Program Files\Java\jdk1.8.0_171\bin> jcmd 24412 JFR.stop 24412: Java Flight Recorder not enabled. Use VM.unlock_commercial_features to enable.