1075 字
约 3 分钟
7
S05-A02 · 线上故障诊断:工具矩阵与 SOP
2024-12-31
2026-11-07

适用读者:线上出现 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. 自检(架构师版)

  1. 三段式定界的顺序为什么不能反?
  2. CPU 不高但接口慢,先看什么?
  3. 为什么线程栈要连续抓 3 次?
  4. jstat -gcutil 里哪个数字最能说明"GC 有问题"?
  5. 记录模板里"验证"段缺失会有什么后果?

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/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。