JVM 统一诊断工具 `jcmd` 使用

JVM 统一诊断工具 jcmd 使用

jcmd(Java Command)是 JDK 7u40 引入的命令行工具,它允许用户向运行中的 Java 虚拟机发送诊断命令。在 JDK 9 以后,jcmd 更是成为了标准诊断的首选工具。

1. 基础用法与命令发现

1.1 列出所有 Java 进程

不带任何参数执行 jcmd,可以列出所有正在运行的 Java 进程及其 PID:

jcmd

输出示例:

Plaintext

12345 DemoApplication.jar
67890 org.jetbrains.idea.Main

1.2 查看可用命令

向特定的 PID 发送 help 命令,可以查看该 JVM 实例当前支持的所有诊断命令。

jcmd <PID> help
# 示例:jcmd 12345 help

输出示例(部分):

Plaintext

The following commands are available:
JFR.start
JFR.stop
JFR.dump
Thread.print
GC.heap_dump
GC.class_histogram
VM.uptime
...

1.3 查看具体命令的帮助信息

可以针对某个具体的命令获取更详细的参数说明。

jcmd <PID> help <CommandName>
# 示例:jcmd 12345 help GC.heap_dump

2. 核心功能及传统工具替代

jcmd 通过不同的命令,实现了对传统工具的全面替代。

2.1 线程分析 (替代 jstack)

用于获取线程堆栈信息,排查死锁、高 CPU 占用等问题。

传统工具 jcmd 命令 作用
jstack <PID> Thread.print 打印线程堆栈(默认包含锁信息)。
jstack -l <PID> Thread.print -l 注意-l 参数作为 Thread.print 的子参数传递。

示例:

# 获取线程堆栈,包含锁信息(等同于 jstack -l)
jcmd 12345 Thread.print -l

提示: jcmd Thread.print 的输出格式与 jstack 完全一致,因此前一节介绍的堆栈分析方法依然适用。

2.2 堆与内存分析 (替代 jmap & jstat)

用于检查堆内存使用情况、查看对象分布或生成堆转储文件。

传统工具 jcmd 命令 作用
jmap -dump GC.heap_dump 生成堆转储文件(HPROF 文件),用于离线分析内存泄漏。
jmap -histo GC.class_histogram 打印类实例数量和占用的字节数,用于识别内存大户。
jstat -gc GC.heap_info 打印 GC 概况和堆区(Eden, Old, Survivor)信息。

示例:

# 1. 生成堆转储文件到指定位置 (必须是绝对路径)
jcmd 12345 GC.heap_dump /tmp/my_app_dump.hprof

# 2. 打印当前活跃对象直方图
jcmd 12345 GC.class_histogram

# 3. 查看堆内存详细信息
jcmd 12345 GC.heap_info

2.3 虚拟机管理 (VM)

提供了一些虚拟机运行时信息的查询和操作。

命令 作用
VM.version 打印 JVM 版本和参数。
VM.uptime 打印 JVM 启动时长(已运行时间)。
VM.system_properties 打印所有系统属性(System Properties)。
VM.commercial_features 打印所有商业功能(如 JFR/JMC)的状态。
GC.run 手动触发 Full GC。生产环境谨慎使用。

示例:

# 查看 JVM 已经运行了多长时间
jcmd 12345 VM.uptime

3. Java Flight Recorder (JFR) 控制 (独有功能)

Java Flight Recorder 是 Oracle 提供的低开销生产环境性能分析工具。jcmd 是管理 JFR 记录的主要工具

3.1 启动 JFR 记录

指定记录名称、配置文件和输出路径:

jcmd <PID> JFR.start name=MyRec duration=60s settings=profile
# name: 记录的名称 (MyRec)
# duration: 持续时间 (60秒后自动停止)
# settings: 使用 JDK 自带的 profile 模板 (高细节)

3.2 停止并导出记录

如果记录是无限期启动的,你需要手动停止并导出数据:

jcmd <PID> JFR.stop name=MyRec filename=/tmp/my_rec_data.jfr

3.3 其他 JFR 命令

  • JFR.dump: 导出当前正在进行的记录数据,但不停止记录。
  • JFR.check: 检查当前正在进行的 JFR 记录状态。

4. 最佳实践总结

场景 推荐 jcmd 命令 目的
高 CPU jcmd <PID> Thread.print -l 配合 top -Hp 定位高耗时线程的堆栈。
内存泄漏 jcmd <PID> GC.heap_dump /path/to/file.hprof 生成堆转储文件,使用 MAT 或 VisualVM 分析。
并发卡顿 jcmd <PID> Thread.print -l (多次采样) 查找大量的 BLOCKEDWAITING 状态线程。
性能基准测试 jcmd <PID> JFR.start ... 在低开销下获取细粒度的 CPU、锁、IO 等性能数据。
posted @ 2025-12-04 17:35  Sappy  阅读(23)  评论(0)    收藏  举报