核心是量化停顿、频率、内存变化三指标;禁用system.gc()后分析真实full gc;用gcviewer看堆趋势与停顿尖峰;结合jstat与日志交叉验证;借助gceasy定位根因并获修复建议。

盯住真实停顿时间,别被 System.gc() 干扰
System.gc() 触发的 Full GC 会造成秒级 STW,但这种停顿和业务压力无关,纯属代码误调用。它会拉高 P99 延迟、导致 K8s 探针失败,却掩盖真实瓶颈。
- 先加 -XX:+DisableExplicitGC 启动参数,让 System.gc() 静默失效
- 禁用后,再观察 jstat -gc 输出里的 FGC 列是否停止异常增长
- GC 日志中不再出现 “(System.gc())” 字样,剩下的 Full GC 才值得深挖
用 GCViewer 看趋势,不是只看单次日志
GCViewer 把文本日志转成图表,一眼就能识别异常模式,比如堆不回落、停顿毛刺、Full GC 规律性爆发。
- 重点看 Heap Usage Over Time:老年代持续爬升不回落 → 暗示内存泄漏或缓存失控
- 关注 Pause Time Distribution:出现 >200ms 的尖峰 → 检查是否 G1 fallback 或 CMS concurrent mode failure
- 对比 Young GC 间隔:从几分钟缩到几十秒 → 可能对象分配过快,或 Survivor 区太小导致提前晋升
结合 jstat 和 GC 日志交叉验证
jstat 提供实时快照,GC 日志记录历史行为,两者对照才能排除偶然抖动。
- 运行 jstat -gc
1000 5 ,看 YGC/YGCT/FGC/FGCT 是否稳定增长 - 若 FGC 次数上升但 FGCT 单次耗时很短 → 可能是元空间耗尽触发的轻量级 Full GC
- 若 E、O 区使用率同步缓慢上涨 → 老年代填满前兆,需查长期存活对象(用 jmap -histo)
让 GCeasy 帮你定位根因,不止于现象
GCeasy 是带机器学习分析能力的在线工具,上传 gc.log 后自动标出风险项,比如“过早晋升”“DirectByteBuffer 泄漏”“Metaspace 接近上限”。
- 它会直接指出哪类对象占老年代最多,比手动翻 jmap -histo 更快定位静态 Map 或 ThreadLocal 持有
- 对 G1 收集器,能识别并发标记失败次数及原因(如 Evacuation Failure 或 Mixed GC 太少)
- 输出报告里带修复建议,比如“建议增大 -XX:MaxMetaspaceSize=512m”或“检查 Netty 的 PooledByteBufAllocator 使用方式”











