直接看GC日志可提前识别回收瓶颈:Allocation Failure频发且Eden使用率>95%、Promotion/Concurrent Mode Failure、FGCT上升且间隔缩短、Young GC后老年代持续上涨,均表明压力积累;需结合回收效率(如Eden回收量、Full GC回收率、Metaspace增长)与时间趋势(时间戳统计、堆占用逐次升高)综合判断,并用GCViewer等工具定位停顿峰值与老年代阶梯式上升等关键异常。

直接看 GC 日志就能发现回收瓶颈在哪,关键不是等系统卡死,而是从日志里读出“压力正在积累”的信号。
盯住四类典型异常日志信号
GC 日志里反复出现的特定关键词,就是瓶颈正在形成的明证:
- Allocation Failure 频繁出现,尤其伴随 Eden 区使用率长期 >95%,说明对象分配速度远超回收能力
- Promotion Failed 或 Concurrent Mode Failure,代表老年代没空间接收晋升对象,往往触发 Full GC
- Full GC 耗时(FGCT)持续上升,且间隔越来越短,比如从每小时 1 次变成每 5 分钟 1 次
- 每次 Young GC 后老年代占用明显上涨(如日志中 Tenured 区从 400M → 600M),说明大量对象过早晋升
对比关键区域的回收效率
不要只看“有没有 GC”,要看“每次 GC 回收了多少”:
- Young GC 后 Eden 区回收量应接近满额(比如 800M → 几十 MB),若回收后仍剩 300M+,说明存活对象太多、Survivor 容不下,被迫晋升
- Full GC 后老年代回收率低于 5%,甚至只下降几 MB,意味着对象长期驻留,可能是内存泄漏或缓存未清理
- Metaspace 使用率持续爬升(日志中 Metaspace 行显示 used 值不断增大),指向类加载器泄漏或动态生成类过多
结合时间维度识别恶化趋势
单次日志看不出问题,连续观察才能定位拐点:
立即学习“Java免费学习笔记(深入)”;
- 用 -XX:+PrintGCTimeStamps 或 -Xlog:gc*:time 确保每条日志带时间戳,便于按小时/天统计频率变化
- 画简易折线图:横轴为时间,纵轴为 Young GC 次数/小时。若曲线陡升,说明业务流量激增或代码逻辑变更(如循环内新建大对象)
- 关注“GC 后堆总占用”是否逐次升高(如 [PSYoungGen: 1024K->512K] [ParOldGen: 2048K->2560K]),这是老年代缓慢泄漏的典型特征
用工具放大问题细节
人工扫日志易漏关键点,工具能快速聚焦瓶颈:
- 用 GCViewer 加载日志后,打开 Pause 折线图,最高点对应那次最久停顿,双击可跳转到原始日志行,确认是 Young GC 还是 Full GC
- 查看 Heap Trend 图,若老年代曲线呈阶梯式上升(每次 Full GC 后不回落),基本锁定长期对象堆积
- 导出 CSV,把每次 GC 的 real time、老年代使用量、GC 类型三列拉出来排序,找出“耗时最长 + 老年代最满”的那几次,重点分析其前后业务操作


















