线上 Full GC 频繁问题排查
凌晨告警群炸了——接口响应超时,服务器 CPU 飙到 300%。登录一看,Full GC 每 5 秒一次。本文还原完整的排查和修复过程。
一、告警与现场
- 1.1 从监控看异常——CPU 飙升、接口 RT 暴涨、GC 频率异常
- 1.2 保留现场的三板斧——
jstack/jmap/jstat
二、GC 日志解读
- 2.1 开启 GC 日志
-Xlog:gc*(JDK 9+)vs-XX:+PrintGCDetails(JDK 8) - 2.2 GC 日志字段逐一解析
- 2.3 GC Easy / GC Viewer 可视化分析
- 2.4 案例日志:每 5 秒一次 Full GC,每次耗时 2s+
三、jstat 实时监控
- 3.1
jstat -gc <pid> 1000查看各代内存变化 - 3.2 S0C/S1C/EC/OC/MC 字段含义
- 3.3 YGC/YGCT/FGC/FGCT 变化趋势分析
- 3.4 老年代持续增长 → Full GC 无法回收 → 内存泄漏
四、jmap 堆 dump 分析
- 4.1
jmap -dump:format=b,file=heap.hprof <pid> - 4.2 注意:Full GC 前 dump 还是手动 GC 后 dump
- 4.3 线上 dump 的风险——STW 时长控制
五、MAT 分析堆 dump
- 5.1 Leak Suspects Report——Dominator Tree
- 5.2 Histogram 按类统计对象数量与大小
- 5.3 Path to GC Roots——找到引用链
- 5.4 案例发现:ThreadLocal 未清理导致大量对象泄漏
- 5.5 OQL 查询辅助定位
六、jstack 线程分析
- 6.1 找出爆 CPU 的线程
top -Hp→printf '%x'→jstack - 6.2 死锁检测
jstack -l - 6.3 大量线程 BLOCKED/Waiting 分析
七、根因定位与修复
- 7.1 案例还原:ThreadLocal + 线程池的内存泄漏
- 7.2 修复代码——try-finally 中 remove()
- 7.3 验证修复——灰度发布 + GC 日志对比
八、预防措施
- 8.1 GC 监控告警配置(Prometheus + JMX Exporter)
- 8.2 代码审查中的内存泄漏 checklist
- 8.3 压测环境增加 GC 日志观察环节
- 8.4 自动化内存泄漏检测工具(Arthas
memory命令)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 谜思录!