深夜两点,告警群突然炸了:某核心服务的堆内存使用率连续 30 分钟超过 95%,Full GC 频率从平时的每 40 分钟一次飙升到每分钟数次,接口 P99 从 120ms 恶化到 3s,紧接着节点开始轮番 OOM 重启。这类场景对每一个后端工程师来说都不陌生。本文以一次真实的生产内存泄漏事故为蓝本,完整复盘从「发现异常」到「定位根因」再到「止血与根治」的全链路排查过程,重点讲清楚 jstat、jmap、jstack、MAT 这些工具各自该在什么时机用、能拿到什么证据、如何互相印证。
一、问题现象:先定性,再动手
拿到告警后的第一件事不是急着 dump 堆,而是先回答三个问题:这是内存泄漏,还是内存本来就不够?是 Full GC 频发导致的暂停,还是年轻代晋升压力过大?是单点问题还是全集群问题?