Java生产环境GC日志是排查FullGC频繁的最直接依据,需结合时间线、回收效果和触发原因三者交叉判断:频率≥1次/分钟属紧急,间隔持续缩短提示内存泄漏前兆,耗时>500ms用户已感知卡顿;老年代占满、元空间满、System.gc()调用、CMS失败四类触发原因各有日志特征;Full GC后老年代used值下降

Java 生产环境 GC 日志是排查 FullGC 过于频繁最直接、最可靠的依据。关键不是看日志里有没有“Full GC”字样,而是结合时间线、回收效果和触发原因三者交叉判断。
确认是否真频繁:盯住频率与趋势
先别急着分析日志细节,快速建立基准判断:
- Full GC 每分钟 ≥1 次 → 紧急级别,必须立刻介入
- Full GC 间隔持续缩短(比如从 30 分钟→15 分钟→5 分钟)→ 典型内存泄漏前兆,比绝对次数更危险
- 单次 Full GC 耗时 >500ms → 用户已明显感知卡顿;>2 秒 → 服务基本不可用
定位触发类型:四类常见原因对应日志特征
打开 GC 日志(如 gc.log),逐行搜索关键词,快速归类:
- 老年代占满型:日志含 Allocation Failure + Eden space exhausted + 后续出现 Full GC。说明对象大量晋升,老年代撑不住了
- 元空间满型:出现 Metaspace allocation failure 或 java.lang.OutOfMemoryError: Metaspace。多见于动态代理、热部署、频繁 defineClass
- System.gc() 主动触发型:明确看到 Full GC (System.gc())。检查代码、框架(如某些旧版 Druid、RMI 默认行为)或监控探针是否调用了它
- CMS 失败型:含 concurrent mode failure 或 promotion failed。说明 CMS 收集器并发阶段没抢赢对象晋升速度,被迫退化为 Serial Old 全停顿
看回收效果:判断是不是内存泄漏
挑出最近 3~5 次 Full GC 日志段,对比每次的回收前后数据:
立即学习“Java免费学习笔记(深入)”;
- 重点关注 old 或 tenured 区的 used 值:GC 后只下降 2%~5%,甚至几乎不降 → 强烈提示内存泄漏
- 对比 capacity 是否稳定:若老年代 capacity 也在涨,可能是堆外内存或元空间干扰,需另查
- 留意 YGC/FGC 比值:健康应用通常 >10:1;若接近 1:1,说明大量对象没活过年轻代就进了老年代
结合工具做深度验证
GC 日志只是起点,必须联动运行时工具验证:
- 用 jstat -gcutil PID 1s 实时观察 O(老年代使用率)是否单向爬升,OU 下降幅度是否越来越小
- 用 jmap -heap PID 看老年代实际容量和当前使用量,确认是否配置过小
- 若怀疑元空间问题,加参数 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 后再看日志中 Metaspace 的 committed 和 used 变化


















