TechBlog
首页分类标签搜索关于

© 2025 TechBlog. All rights reserved.

JDK-自带命令行诊断工具复习

12/22/2025
未分类#开发语言#Java

微信小程序星海飞驰

JDK 自带命令行诊断工具复习

一、JDK 自带命令行诊断工具概览

这些工具位于 $JAVA_HOME/bin/ 目录下,无需额外依赖,适用于 开发调试、测试验证、生产应急排查。

工具全称主要用途
jpsJVM Process Status Tool列出当前用户运行的 Java 进程
jstatJVM Statistics Monitoring Tool实时监控 GC、类加载、内存等统计信息
jmapMemory Map for Java查看堆内存结构,生成 heap dump
jstackStack Trace for Java打印线程栈,分析死锁、阻塞
jinfoConfiguration Info for Java查看/修改部分 JVM 启动参数
jcmdJVM Command Tool多功能统一入口(JDK 7+ 推荐)
jhatJVM Heap Analysis Tool分析 heap dump(已过时)

⚠️ 注意:从 JDK 9 起,部分 GUI 工具(如 jvisualvm)不再默认包含,但命令行工具仍完整保留。

二、各工具详解 + 实战示例

1. jps —— 快速定位 Java 进程

解决什么问题?
快速找到目标 Java 应用的 PID(进程 ID),为后续诊断做准备。


# 列出所有 Java 进程(简略)
jps

# 显示主类全名或 jar 路径
jps -l

# 显示 JVM 启动参数
jps -v

✅ 示例输出:


12345 Bootstrap          # Tomcat
67890 myapp.jar

✅ 面试提示:在容器化环境(Docker/K8s)中,jps 可能看不到其他容器的进程,需进入目标容器执行。

2. jstat —— 实时监控 GC 与内存

解决什么问题?

  • 判断是否存在频繁 Full GC
  • 分析 Young GC 是否正常
  • 观察 Metaspace 是否泄漏

# 每 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 泄漏)

3. 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)中的泄漏点。

4. jstack —— 线程栈分析

解决什么问题?

  • CPU 飙高(结合 top -H 找线程 ID)
  • 线程死锁、阻塞、WAITING 过久
  • 线程池任务堆积

# 打印所有线程栈
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% 排查流程:

  1. top 找到高 CPU 的 Java 进程 PID
  2. top -Hp <PID> 找到高 CPU 的线程 TID(十进制)
  3. printf "%x\n" <TID> 转为十六进制(如 2b3a)
  4. jstack <PID> | grep -A 50 "2b3a" 定位该线程代码

5. 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。

三、高级 Java 面试经典问题 & 回答要点

❓1. 线上服务 CPU 使用率突然飙升到 100%,如何排查?

✅ 标准回答路径:

  1. top 找到高 CPU 的 Java 进程 PID
  2. top -Hp <PID> 找到具体高 CPU 的线程 TID
  3. 将 TID 转为 16 进制(printf "%x\n" <TID>)
  4. jstack <PID> | grep -A 50 "<hex_tid>" 定位线程栈
  5. 分析代码:是否死循环?正则回溯?HashMap 扩容?
  6. 若频繁发生,考虑用 Async-Profiler 生成火焰图

💡 加分项:提到“避免直接 kill”,先抓现场(jstack + jmap)再重启。


❓2. 如何判断 Java 应用是否存在内存泄漏?

✅ 回答要点:

  • 使用 jstat -gcutil 观察 Old 区使用率是否持续上升,Full GC 后无法下降
  • 用 jmap -histo 查看可疑对象数量是否不断增长
  • 生成 heap dump(jmap -dump),用 MAT 分析:
    • 查看 Dominator Tree
    • 检查 GC Roots 引用链(如静态集合、未关闭的监听器)
  • 常见泄漏源:缓存未清理、ThreadLocal 未 remove、Observer 未注销

💡 加分项:提到“Metaspace 泄漏”(动态生成类未卸载,如 cglib、Groovy 脚本)


❓3. jmap 和 jstack 在生产环境使用有什么风险?

✅ 专业回答:

  • jmap -dump 会触发 Stop-The-World,导致应用暂停(几秒到几十秒),影响 SLA
  • jstack 虽轻量,但在极端情况下也可能短暂暂停 JVM
  • 建议:
    • 在低峰期操作
    • 使用 jcmd 替代(部分命令更安全)
    • 优先通过 JMX 或 APM(如 SkyWalking、Arthas)远程诊断
    • 开启 -XX:+HeapDumpOnOutOfMemoryError 自动 dump

❓4. 你用过哪些 JDK 诊断工具组合来解决实际问题?

✅ 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优先使用

五、延伸建议(高级开发者)

  • 学习 Arthas(阿里开源):在线 watch、trace、反编译,无需重启
  • 掌握 Async-Profiler:低开销生成 CPU/内存火焰图
  • 熟悉 JMX + Prometheus + Grafana:构建生产监控体系
  • 了解 Java Flight Recorder (JFR)(JDK 11+ 商业特性免费):飞行记录器,近乎零开销

微信小程序星海飞驰