JVM(Java Virtual Machine)性能监控是保障 Java 应用稳定运行和性能优化的重要手段。通过一系列命令行工具,我们可以对 JVM 的运行状态、内存使用、线程状况、GC 行为等进行深入分析。
一、常用 JVM 性能监控命令
命令 | 功能 |
---|---|
jps | 查看本地正在运行的 Java 进程 |
jstat | 监控 JVM 内存和垃圾回收统计信息 |
jinfo | 查看和修改 JVM 配置参数 |
jmap | 生成堆内存快照(heap dump)或查看堆内存详细信息 |
jhat | 分析 heap dump 文件(不推荐,已被替代) |
jstack | 生成线程快照,用于分析死锁、线程阻塞等问题 |
jcmd | 综合型诊断工具,支持多种 JVM 操作 |
VisualVM / JConsole / JMC | 图形化监控工具 |
二、各命令详解与实战应用
1. jps
:查看 Java 进程
jps -l
-
输出:
12345 com.example.MyApp
-
作用:列出当前机器上所有 Java 进程的 PID 和主类名。
-
适用场景:配合其他命令使用,如 jstat、jmap 等。
2. jstat
:JVM 统计监控工具
常用格式:
jstat -gc <pid> [interval] [count]
-
示例:
jstat -gc 12345 1000 5
-
输出字段含义:
字段 | 含义 |
---|---|
S0C/S1C | Survivor 0/1 区容量(KB) |
S0U/S1U | Survivor 0/1 区已使用容量(KB) |
EC/EU | Eden 区容量及使用量 |
OC/OU | Old 区容量及使用量 |
MC/MU | Metaspace 容量及使用量 |
CCSC/CCSU | 压缩类空间容量及使用量 |
YGC/YGCT | 新生代 GC 次数和耗时 |
FGC/FGCT | Full GC 次数和耗时 |
GCT | 所有 GC 总时间 |
- 用途:监控 GC 频率、内存分配情况、判断是否存在内存泄漏。
3. jinfo
:查看或设置 JVM 参数
查看 JVM 参数:
jinfo <pid>
只查看系统属性和 JVM 参数:
jinfo -flags <pid>
修改可动态调整的参数(部分参数支持):
jinfo -flag [+/-]<name> <pid>
例如开启 PrintGC:
jinfo -flag +PrintGC 12345
- 注意:不是所有参数都支持动态修改。
4. jmap
:堆内存分析工具
查看堆内存概况:
jmap -heap <pid>
生成堆转储文件(heap dump):
jmap -dump:live,format=b,file=heap.bin <pid>
- 用途:分析内存泄漏、对象占用情况,通常配合 MAT(Memory Analyzer Tool) 使用。
查看对象实例数量统计:
jmap -histo <pid> | head -n 20
输出示例:
num #instances #bytes class name
---------------------------------------------
1: 12345678 123456789 [C
2: 1234567 12345678 java.lang.String
- 用途:快速识别大对象或频繁创建的对象。
5. jstack
:线程快照分析工具
获取线程堆栈信息:
jstack <pid> > thread_dump.log
-
关键信息:
- 线程状态(RUNNABLE、BLOCKED、WAITING)
- 线程持有锁、等待锁
- 是否发生死锁(自动检测)
-
用途:
- 分析线程阻塞、死锁问题
- 判断是否有线程长时间阻塞在 I/O 或数据库操作
6. jcmd
:多功能综合诊断命令
列出可用命令:
jcmd <pid> help
常用命令示例:
-
生成线程快照:
jcmd <pid> Thread.print
-
生成 heap dump:
jcmd <pid> GC.heap_dump /path/to/dump.hprof
-
查看 JVM 参数:
jcmd <pid> VM.flags
-
查看类加载信息:
jcmd <pid> VM.classloader_stats
-
执行 GC:
jcmd <pid> GC.run
-
优势:比多个单独命令更统一、功能更强。
三、图形化工具推荐
工具 | 特点 |
---|---|
VisualVM | 免费、开源,支持远程连接,可查看 CPU、内存、线程、GC、类加载等 |
JConsole | JDK 自带,简单易用,适合基础监控 |
JMC (Java Mission Control) | 商业级监控,低开销,支持飞行记录器(Flight Recorder),适合生产环境 |
MAT (Memory Analyzer) | 分析 heap dump,查找内存泄漏根源 |
Arthas (Alibaba 开源) | 强大的在线诊断工具,支持热更新、反编译、方法追踪等 |
四、案例:如何排查一次 Full GC 频繁问题
步骤如下:
-
使用 jps 查找目标进程
jps -l
-
使用 jstat 观察 GC 情况
jstat -gc 12345 1s 10
- 关注
FGC
字段是否频繁增长,FGCT
是否显著增加。
- 关注
-
使用 jmap 生成堆转储
jmap -dump:live,format=b,file=heap.bin 12345
-
使用 MAT 打开 heap.bin 分析
- 查看 Dominator Tree,找出占用内存最多的对象
- 检查是否有内存泄漏(如缓存未释放、监听器未注销等)
-
结合 jstack 分析线程行为
jstack 12345 > thread.log
- 检查是否有大量线程处于 WAITING/BLOCKED 状态
-
根据分析结果优化代码或调优 JVM 参数
五、建议与最佳实践
- 定期监控 GC 情况:避免频繁 Full GC 导致服务卡顿。
- 合理配置堆大小:Xms/Xmx 设置相同,减少内存抖动。
- 避免内存泄漏:及时释放无用对象,特别是静态集合类、监听器、ThreadLocal。
- 启用 Native Memory Tracking(NMT):排查 native 内存泄露
-XX:NativeMemoryTracking=summary jcmd <pid> VM.native_memory summary
- 使用 Arthas 在线诊断复杂问题:如方法耗时、异常堆栈、SQL 执行等。
六、总结
场景 | 推荐命令 |
---|---|
查看 Java 进程 | jps |
监控内存与 GC | jstat |
查看 JVM 参数 | jinfo |
分析堆内存 | jmap |
分析线程问题 | jstack |
多功能诊断 | jcmd |
可视化监控 | VisualVM / JMC |
内存泄漏分析 | MAT |
生产环境在线诊断 | Arthas |