JVM GC 停顿排查:从日志判断内存压力与回收效率

利用 GC 日志、堆占用和分配速率区分正常停顿、对象晋升、内存泄漏与堆外压力。

文章目录 · 4 节

应用延迟尖峰与 GC 同时出现,并不意味着“把堆调大”就能解决。停顿可能来自高分配速率、老年代回收、元空间增长或容器内存边界不合理。

收集低风险证据

jcmd $PID VM.flags
jcmd $PID GC.heap_info
jstat -gcutil $PID 1000 20
jcmd $PID VM.native_memory summary

生产环境应优先分析已启用的 GC 日志。jmap -dump 可能造成长暂停和大量磁盘写入,必须经过容量和影响评估。

阅读 GC 事件

-Xlog:gc*,safepoint:file=/var/log/app/gc.log:time,uptime,level,tags

关注暂停原因、回收前后占用、事件频率和晋升失败。堆在 Full GC 后仍持续抬升才更像存活对象泄漏;高频 Young GC 则常与分配速率和对象生命周期有关。

调优顺序

  • 先确认容器 limit 与 JVM 最大内存、堆外内存的关系
  • 用 JFR 或 profiler 找到分配热点和锁等待
  • 根据延迟目标选择 G1、ZGC 等收集器,而非照搬参数
  • 每次只改变少量参数并保留对照数据

收尾清单

用同一业务负载比较吞吐、P99、GC 时间占比和 RSS。将 GC 日志纳入集中采集,但避免把对象明细等敏感信息长期保留。