文章目录
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)