
这些工具位于 $JAVA_HOME/bin/ 目录下,无需额外依赖,适用于 开发调试、测试验证、生产应急排查。
| 工具 | 全称 | 主要用途 |
|---|---|---|
jps | JVM Process Status Tool | 列出当前用户运行的 Java 进程 |
jstat | JVM Statistics Monitoring Tool | 实时监控 GC、类加载、内存等统计信息 |
jmap | Memory Map for Java | 查看堆内存结构,生成 heap dump |
jstack | Stack Trace for Java | 打印线程栈,分析死锁、阻塞 |
jinfo | Configuration Info for Java | 查看/修改部分 JVM 启动参数 |
jcmd | JVM Command Tool | 多功能统一入口(JDK 7+ 推荐) |
jhat | JVM Heap Analysis Tool | 分析 heap dump(已过时) |
⚠️ 注意:从 JDK 9 起,部分 GUI 工具(如
jvisualvm)不再默认包含,但命令行工具仍完整保留。
jps —— 快速定位 Java 进程解决什么问题?
快速找到目标 Java 应用的 PID(进程 ID),为后续诊断做准备。
# 列出所有 Java 进程(简略)
jps
# 显示主类全名或 jar 路径
jps -l
# 显示 JVM 启动参数
jps -v
✅ 示例输出:
12345 Bootstrap # Tomcat
67890 myapp.jar
✅ 面试提示:在容器化环境(Docker/K8s)中,
jps可能看不到其他容器的进程,需进入目标容器执行。
jstat —— 实时监控 GC 与内存解决什么问题?
# 每 2 秒输出一次 GC 统计,共 5 次
jstat -gc 12345 2000 5
关键字段说明:
S0C/S1C:Survivor 区容量EC:Eden 区容量OC:Old 区容量YGC/YGCT:Young GC 次数 / 总耗时FGC/FGCT:Full GC 次数 / 总耗时GCT:总 GC 耗时✅ 典型问题判断:
FGC 持续增长 → 可能存在内存泄漏或老年代不足YGCT 占比过高 → 对象晋升过快,可能 Eden 太小🔍 进阶用法:
jstat -gcutil 12345 1000 # 以百分比显示内存使用率 jstat -class 12345 # 查看类加载数量(排查 Metaspace 泄漏)
jmap —— 内存快照与对象分布解决什么问题?
# 生成 heap dump(用于离线分析)
jmap -dump:format=b,file=heap_20251222.hprof 12345
# 查看堆内存概要(不生成 dump)
jmap -heap 12345
# 统计对象数量(前 20)
jmap -histo 12345 | head -20
✅ 示例输出(-histo):
num #instances #bytes class name
----------------------------------------------
1: 100000 8000000 java.lang.String
2: 50000 4000000 com.example.CacheEntry
⚠️ 警告:
jmap -dump会触发 Stop-The-World,生产环境慎用!建议在低峰期操作,或使用-F强制(风险更高)。
✅ 最佳实践:配合 Eclipse MAT 或 VisualVM 分析
.hprof文件,快速定位“支配树”(Dominator Tree)中的泄漏点。
jstack —— 线程栈分析解决什么问题?
top -H 找线程 ID)
# 打印所有线程栈
jstack 12345 > thread_dump.txt
✅ 分析死锁示例:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f... (object A)
which is held by "Thread-2"
"Thread-2":
waiting to lock monitor 0x00007f... (object B)
which is held by "Thread-1"
✅ CPU 100% 排查流程:
top 找到高 CPU 的 Java 进程 PIDtop -Hp <PID> 找到高 CPU 的线程 TID(十进制)printf "%x\n" <TID> 转为十六进制(如 2b3a)jstack <PID> | grep -A 50 "2b3a" 定位该线程代码jcmd —— 现代化统一诊断入口(推荐!)解决什么问题?
替代多个旧工具,提供更安全、更丰富的命令。
# 查看支持的命令
jcmd 12345 help
# 打印线程栈(等价 jstack)
jcmd 12345 Thread.print
# 手动触发 GC(仅测试用!)
jcmd 12345 GC.run
# 查看 JVM 启动参数
jcmd 12345 VM.flags
# 生成 heap dump
jcmd 12345 GC.run_finalization
jcmd 12345 VM.unlock_commercial_features # (需商业版 JDK)
✅ 优势:比
jmap/jstack更轻量,部分操作不会 STW。
✅ 标准回答路径:
top 找到高 CPU 的 Java 进程 PIDtop -Hp <PID> 找到具体高 CPU 的线程 TIDprintf "%x\n" <TID>)jstack <PID> | grep -A 50 "<hex_tid>" 定位线程栈💡 加分项:提到“避免直接 kill”,先抓现场(jstack + jmap)再重启。
✅ 回答要点:
jstat -gcutil 观察 Old 区使用率是否持续上升,Full GC 后无法下降jmap -histo 查看可疑对象数量是否不断增长jmap -dump),用 MAT 分析:
💡 加分项:提到“Metaspace 泄漏”(动态生成类未卸载,如 cglib、Groovy 脚本)
✅ 专业回答:
jmap -dump 会触发 Stop-The-World,导致应用暂停(几秒到几十秒),影响 SLAjstack 虽轻量,但在极端情况下也可能短暂暂停 JVMjcmd 替代(部分命令更安全)-XX:+HeapDumpOnOutOfMemoryError 自动 dump✅ STAR 法则示例回答:
Situation:某次大促后,订单服务响应变慢,Old 区持续增长。
Task:需在 30 分钟内定位是否内存泄漏。
Action:
jstat -gcutil确认 Full GC 后 Old 区仍达 90%+jmap -histo发现OrderCache对象超 200 万实例- 生成 heap dump,MAT 分析发现被
static Map引用,未设置 TTL
Result:修复缓存策略,内存稳定,避免宕机。
| 场景 | 推荐工具 | 注意事项 |
|---|---|---|
| 快速看进程 | jps | 容器内执行 |
| GC 监控 | jstat -gcutil | 长期观察趋势 |
| 内存泄漏 | jmap -dump + MAT | 避免高峰使用 |
| 线程问题 | jstack / jcmd Thread.print | 结合 CPU 分析 |
| 综合诊断 | jcmd | 优先使用 |
