1075 字
约 3 分钟
7
S05-A02 · 线上故障诊断:工具矩阵与 SOP
适用读者:线上出现 OOM、CPU 100%、接口变慢时要独立定界的人。
前置:S05-J04、S05-A01。
实测环境:OpenJDK 21.0.12.1 / Ubuntu 24.04.1(jcmd、jstack、jstat、-Xlog:gc可用性实测)。
覆盖旧文:A-1131(474) A-2580(623) A-2579(407) A-2578(305) A-1622(242) A-1638(133) + 1634(244) = 2,428 点。
覆盖扩展:E-S05-017(工具矩阵)、E-S05-018(三段式定界 SOP)。
上一篇:S05-A01 · GC 收集器选型与调优
下一篇:S05-X01 · 八股速查。
1. 一句话结论
JVM 排障的全部难点不在工具,在"先定界":是内存问题、CPU 问题,还是锁/线程问题。定界错了,工具再多也是白查。
2. 工具矩阵(E-S05-017)
| 症状 | 首查工具 | 命令示例 | 看什么 |
|---|---|---|---|
| 内存涨/OOM | jmap / jcmd |
jcmd <pid> GC.heap_info、jmap -histo:live <pid> |
回收后占用、对象直方图 |
| CPU 100% | top -H + jstack |
top -H -p <pid> → jstack <pid> | grep -A 20 <nid> |
哪个线程在跑什么 |
| 接口变慢 | jstat / GC 日志 |
jstat -gcutil <pid> 1000 |
Full GC 次数与耗时 |
| 死锁 | jstack |
jstack <pid> | grep -A 5 deadlock |
Found one Java-level deadlock |
| 线程池排队 | jstack + 监控 |
线程名 + Thread.State |
队列长度、阻塞点 |
| GC 异常 | -Xlog:gc* |
日志文件 | Evacuation Failure、Full GC |
实测可用性(本机 JDK 21):
$ jcmd -h → Usage: jcmd <pid | main class> <command ...>
$ java -Xlog:gc:stdout → 正常输出 G1 日志
3. 三段式定界 SOP(E-S05-018)
第 1 段:现象定界(1 分钟)
① 是整个服务还是某个接口?→ 看监控/日志
② 是"越来越慢"还是"突然卡"?→ 前者像泄漏,后者像 GC/锁
③ 重启能恢复吗?→ 能且复发 = 泄漏;不能 = 依赖故障
第 2 段:资源定界(3 分钟)
④ CPU 高?→ 线程栈
⑤ CPU 不高但慢?→ 等锁/等 IO(jstack 看 BLOCKED/WAITING)
⑥ 内存高?→ heap_info + 直方图
⑦ GC 频繁?→ jstat gcutil(看 Full GC 次数增长)
第 3 段:代码定界(10 分钟)
⑧ 抓一次线程栈(连续 3 次,间隔 10s)→ 找"停在同一个业务方法"的线程
⑨ 必要时 dump 堆(jmap -dump)→ MAT/直方图分析
⑩ 记录:现象/证据/结论/处置/验证(模板见 §4)
关键技巧:连续抓 3 次栈——如果同一个方法总在里面,那才是热点;抓一次容易被巧合误导。
4. 记录模板
## 现象
14:20 起,订单接口 P99 从 180ms 涨到 4.2s,重启后 30 分钟复发
## 定界
- 资源:CPU 35%(不高);jstat 显示 Full GC 从 0 涨到 47 次,单次 2.8s
- 内存:heap_info 显示老年代回收后仍占 92%
- 代码:jstack ×3 抓到同一方法(OrderCache.loadAll)在 3 次里都出现
## 结论
OrderCache 全量加载未释放旧引用 → 内存泄漏 → 频繁 Full GC → 接口变慢
## 处置
修缓存失效逻辑;临时扩容 + 重启
## 验证
Full GC 次数 24h 内为 0;P99 回落 180ms
5. 五个误区
| 误区 | 真相 |
|---|---|
| "CPU 高就是代码死循环" | 也可能是 GC 线程在跑 |
| "重启就好说明没事" | 复发 = 有泄漏/资源未释放 |
| "抓一次线程栈就够" | 要连续抓,找稳定热点 |
| "内存高就加堆" | 泄漏加堆只是拖时间 |
| "GC 日志影响性能" | 现代 JVM 开销可忽略,且是唯一证据来源 |
6. 自检(架构师版)
- 三段式定界的顺序为什么不能反?
- CPU 不高但接口慢,先看什么?
- 为什么线程栈要连续抓 3 次?
jstat -gcutil里哪个数字最能说明"GC 有问题"?- 记录模板里"验证"段缺失会有什么后果?
7. 下一篇
S05-X01 · 并发与 JVM 八股速查
最后一篇是附录索引:把 6 张面试大卡压成"题 → 一句话答案 → 正文位置"。
本篇属于系列《S05 · Java 并发与 JVM》。旧文来源:A-1131/2580/2579/2578/1622/1638/1634;扩展点 E-S05-017/018。工具可用性为 OpenJDK 21 实测。
S05-A02 · 线上故障诊断:工具矩阵与 SOP
https://www.clxhxhhr.top/posts/5253/ 评论
0 条
还没有评论,先写一条吧。