以下是 JVM 监控与故障处理常用工具及命令的详细说明,涵盖 命令行工具 和 图形化工具,帮助快速定位内存泄漏、高 CPU、死锁等问题:
一、基础命令行工具(JDK 自带)
1. jps:查看 Java 进程
-
用途:快速列出当前用户的所有 Java 进程及其主类、JVM 参数。
-
命令示例:
jps -lvm # 显示详细信息(PID、主类、JVM 参数) -
输出示例:
1234 com.example.MainApp -Xmx2G 5678 sun.tools.jps.Jps -lvm
2. jstat:监控 JVM 统计信息
-
用途:实时查看堆内存、GC 活动、类加载等数据。
-
常用选项:
jstat -gc <pid> 1000 10 # 每 1 秒输出一次 GC 数据,共 10 次 jstat -gcutil <pid> # 显示各内存区域使用百分比 -
关键指标:
S0C/S1C:Survivor 区容量。EU:Eden 区使用量。OGC/OU:老年代容量/使用量。YGC/YGCT:Young GC 次数/耗时。FGC/FGCT:Full GC 次数/耗时。
3. jinfo:查看/修改 JVM 参数
-
用途:动态查看或调整运行中 JVM 的参数。
-
示例:
jinfo -flags <pid> # 查看所有 JVM 参数 jinfo -flag +PrintGC <pid> # 启用 GC 日志打印
4. jmap:生成堆内存快照(Heap Dump)
-
用途:分析内存泄漏、对象分布。
-
常用命令:
jmap -dump:format=b,file=heap.hprof <pid> # 生成堆转储文件 jmap -histo <pid> # 显示堆中对象统计(直方图) -
分析工具:使用 MAT(Memory Analyzer Tool) 或 VisualVM 分析
.hprof文件。
5. jstack:生成线程快照
-
用途:诊断线程死锁、高 CPU 问题。
-
命令示例:
jstack -l <pid> > thread_dump.txt # 输出线程栈信息到文件 -
分析技巧:
- 死锁检测:搜索输出中的
deadlock关键字。 - 高 CPU 线程:结合
top -Hp <pid>找到高 CPU 线程 ID,转换为 16 进制后搜索线程栈。
- 死锁检测:搜索输出中的
6. jcmd:多功能诊断工具(JDK 7+)
-
用途:替代部分
jmap、jstack功能,支持更多操作。 -
示例:
jcmd <pid> GC.heap_dump filename=heap.hprof # 生成堆转储 jcmd <pid> Thread.print # 打印线程栈(同 jstack) jcmd <pid> VM.flags # 查看 JVM 参数
二、图形化工具
1. JConsole
-
启动方式:命令行输入
jconsole。 -
功能:
- 实时监控堆内存、线程、类加载、MBean。
- 检测死锁、手动执行 GC。
-
适用场景:快速查看 JVM 总体状态。
2. VisualVM
-
启动方式:命令行输入
jvisualvm。 -
功能:
- 分析堆转储、线程转储。
- 抽样器(Sampler)监控 CPU、内存分配。
- 安装插件(如 Visual GC)增强功能。
-
优势:集成多种工具,适合深入分析。
3. Java Mission Control(JMC)
-
用途:配合 JDK Flight Recorder(JFR) 进行高性能监控。
-
启用 JFR:
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder ... -
功能:低开销记录 CPU、内存、IO 事件,生成详细分析报告。
三、高级工具与技巧
1. JDK 自带的故障诊断工具(JHSDB)
-
用途:分析堆、线程、查看 JVM 内部数据结构(JDK 9+)。
-
启动:
jhsdb clhsdb # 命令行模式 jhsdb jmap --pid <pid> --dumpfile heap.hprof # 生成堆转储
2. Arthas(阿里开源诊断工具)
-
功能:动态跟踪方法调用、反编译代码、监控线程状态。
-
常用命令:
dashboard # 实时监控面板 thread -n 3 # 查看最忙的 3 个线程 watch com.example.Service * '{params, returnObj}' # 观察方法入参和返回值
3. GC 日志分析
-
启用 GC 日志:
-Xlog:gc*:file=gc.log:time:filecount=5,filesize=10M # JDK 9+ -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log # JDK 8 -
分析工具:使用 GCViewer 或 GCEasy 可视化分析 GC 日志。
四、典型故障排查流程
1. 内存泄漏(OOM)
-
步骤:
- 使用
jmap或jcmd生成堆转储。 - 用 MAT 分析大对象,查找
Retained Heap高的对象。 - 检查代码中未关闭的资源(如数据库连接、流)。
- 使用
2. CPU 使用率过高
-
步骤:
top -Hp <pid>找到高 CPU 线程 ID。- 将线程 ID 转换为 16 进制(如
printf "%x" 1234)。 jstack <pid>查找对应线程栈,定位问题代码。
3. 线程死锁
-
步骤:
jstack <pid>查看线程栈。- 搜索
deadlock关键字,查看死锁的线程和锁信息。 - 检查代码中的同步块或锁顺序。
五、命令速查表
| 场景 | 工具/命令 | 关键参数 |
|---|---|---|
| 查看 Java 进程 | jps | -lvm 显示详细信息 |
| 监控 GC 活动 | jstat | -gc、-gcutil |
| 生成堆转储 | jmap、jcmd | -dump、GC.heap_dump |
| 分析线程栈 | jstack、jcmd | Thread.print |
| 动态调整参数 | jinfo | -flag |
| 图形化监控 | VisualVM、JConsole | 安装插件增强功能 |
| 低开销记录 | JFR | -XX:+FlightRecorder |
| 在线诊断 | Arthas | dashboard、thread、watch |
六、注意事项
- 生产环境谨慎操作:生成堆转储或频繁监控可能影响应用性能。
- 权限问题:部分工具(如
jmap)需要与目标 JVM 相同的用户权限。 - JDK 版本适配:部分命令(如
jcmd、JFR)需特定 JDK 版本支持。
掌握这些工具和命令,结合日志分析,能高效定位 JVM 性能问题。实践中建议先通过监控收集数据,再针对性深入分析。