直接通过GC日志中YGC频率高、Eden区反复满、Survivor使用率低、频繁Promotion Failed或Evacuation Failure等现象,可快速定位年轻代空间不足;需优先调大-Xmn并合理设置-XX:SurvivorRatio。

直接看 GC 日志里年轻代(Young Gen)的回收频率、每次回收后存活对象大小、以及是否频繁触发 Full GC 或 promotion failure,就能快速定位年轻代空间不足。
关注关键日志模式:YGC 频繁且 Eden 区几乎每次都被填满
年轻代空间不足最典型的信号是:Eden 区刚分配完就触发 Minor GC,且 GC 前后 Eden 使用率长期接近 100%。例如:
2024-05-20T10:12:33.456+0800: 123.456: [GC (Allocation Failure) [PSYoungGen: 524288K->12345K(524288K)] 524288K->123456K(1048576K), 0.0421234 secs]这里 PSYoungGen: 524288K->12345K 表示 Eden + Survivor 总容量 524288K(即 512MB),GC 前已用满,GC 后只剩 12MB —— 说明几乎所有对象都被清掉,但下一秒又迅速填满。如果这种日志每秒出现多次,基本可判定年轻代太小。
检查 Survivor 区是否过小,导致对象提前晋升
年轻代空间不足不单指 Eden 小,也可能是 Survivor 区太小,无法容纳一轮 GC 后的存活对象,被迫把大量对象直接晋升到老年代,加剧老年代压力,甚至引发 Full GC。日志中典型线索有:
- Survivor 区使用率长期为 0 或极低(如
PSYoungGen: ...->0K(...)),说明对象没机会在 Survivor 存活,直接晋升 - 日志中出现 “Desired survivor size” 远大于实际分配的 Survivor 空间,比如:
Desired survivor size 262144 bytes, new threshold 7 (max 7)
但实际 Survivor 只有 64KB,就会触发提前晋升 - Minor GC 后老年代占用突增(如
524288K->123456K中后者增长远超正常晋升量),暗示大量对象“逃逸”进老年代
识别 promotion failure 和 concurrent mode failure(CMS)或 Evacuation Failure(G1)
这是年轻代空间严重不足的“高危警报”:
-
Parallel / PS 收集器:日志中出现
Promotion Failed,意味着 Survivor 装不下存活对象,又无法晋升到老年代(老年代也没空间),会退化为 Full GC -
CMS 收集器:出现
concurrent mode failure,常因年轻代 GC 太快、老年代碎片多或空间不足,根本原因是年轻代压力传导至老年代 -
G1 收集器:出现
Evacuation Failure或to-space exhausted,说明 CSet 中对象无法复制到可用 Region,通常因年轻代区域(Young Regions)分配过快、Survivor 区不足或堆整体紧张
针对性调优建议
确认问题后,优先按以下顺序调整:
- 适当增大
-Xmn(或-XX:NewRatio)提高年轻代总大小,让 Eden 有缓冲空间 - 用
-XX:SurvivorRatio(如设为 8)确保 Survivor 区占年轻代合理比例(默认常为 8,即 Eden : S0 : S1 = 8:1:1),避免过小导致早晋升 - 若对象生命周期短且波动大,启用
-XX:+UseAdaptiveSizePolicy(默认开启),让 JVM 动态调节 Eden/Survivor 比例 - 结合
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps持续观察 YGC 间隔、耗时、晋升量变化,验证调优效果
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











