面试官:你排查过JVM问题吗?有哪些常见命令?

221 阅读3分钟

以下是 JVM 常见问题排查的命令及工具,覆盖 ​内存泄漏、CPU 飙高、线程阻塞、GC 异常 等场景,按使用场景分类整理:


一、基础进程与配置查看

1. 查看 Java 进程列表

jps -l  # 列出所有 Java 进程的 PID 和主类名

2. 查看 JVM 启动参数

jinfo -flags <PID>  # 显示指定进程的 JVM 参数

二、内存问题排查

1. 内存分布与 GC 统计

jstat -gcutil <PID> 1000 10  # 每隔1秒采样GC情况,共10次
  • 关键列

    • YGC/YGCT:Young GC 次数/耗时
    • FGC/FGCT:Full GC 次数/耗时
    • O:老年代使用率(>90% 可能有内存泄漏)

2. 生成堆转储文件(Heap Dump)​

jmap -dump:live,format=b,file=heap.hprof <PID>  # 生成堆快照(live 表示只保留存活对象)

3. 堆内存分布直方图

jmap -histo:live <PID> | head -n 20  # 显示存活对象的内存占用排名前20

三、线程与 CPU 问题排查

1. 查看线程堆栈

jstack <PID> > jstack.log  # 生成线程快照
  • 定位高 CPU 线程

    1. 用 top -H -p <PID> 找到高 CPU 的线程 ID(TID)
    2. 将 TID 转为 16 进制:printf "%x\n" <TID>
    3. 在 jstack.log 中搜索 nid=0x<TID_HEX>

2. 检测死锁

jstack <PID> | grep -A 10 "deadlock"  # 检查死锁信息

四、GC 日志与调优

1. 启用 GC 日志

# JDK 8及之前
-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

# JDK 9+
-Xlog:gc*,gc+heap=debug:file=gc.log:time,uptime:filecount=5,filesize=1024

2. 分析 GC 日志工具

  • GCEasy:在线分析 GC 日志(gceasy.io)
  • GCViewer:本地图形化分析工具

五、高级诊断工具

1. 多功能命令 jcmd

jcmd <PID> VM.flags          # 查看 JVM 参数
jcmd <PID> GC.heap_info      # 显示堆内存信息
jcmd <PID> Thread.print      # 等同于 jstack
jcmd <PID> GC.run            # 手动触发 Full GC

2. 可视化监控(JMC)​

jmc  # 启动 Java Mission Control,实时监控 CPU、内存、线程等

3. 在线诊断(Arthas)​

# 启动 Arthas
java -jar arthas-boot.jar

# 常用命令
dashboard    # 实时监控面板
thread -n 3  # 查看最忙的3个线程
monitor -c 5 com.example.Service *  # 监控某个方法的调用统计

六、内存泄漏排查流程

  1. 步骤 1jstat 观察老年代是否持续增长且 Full GC 后无法回收。
  2. 步骤 2jmap -dump 生成堆快照,用 ​MAT(Memory Analyzer Tool)​ 分析。
  3. 步骤 3:在 MAT 中查看 ​Dominator Tree 或 ​Leak Suspects Report,找到大对象或重复对象。

七、命令总结表

命令/工具场景示例
jps查看 Java 进程jps -l
jstatGC 统计与内存分布jstat -gcutil <PID> 1000 5
jmap堆转储与内存直方图jmap -dump:format=b,file=heap.hprof <PID>
jstack线程堆栈与死锁检测jstack <PID> > thread.log
jcmd综合诊断jcmd <PID> VM.flags
Arthas在线动态诊断thread -b 查找阻塞线程

注意事项

  1. 生产环境慎用jmap 和 Full GC 可能引发 STW 停顿。
  2. 权限问题:部分命令需要与目标 JVM 相同的用户权限执行。
  3. 工具结合:结合 ​APM 工具​(如 SkyWalking、Pinpoint)长期监控。

掌握这些命令可快速定位 JVM 常见问题,建议提前在测试环境演练。