-XX:SurvivorRatio=8会加剧Promotion Failed,因其使两个Survivor区合计仅占年轻代20%,空间过小导致Minor GC后存活对象溢出直接晋升老年代;若老年代剩余空间不足或碎片化,即触发Promotion Failed并引发Full GC。

为什么 -XX:SurvivorRatio=8 会加剧 Promotion Failed
默认 -XX:SurvivorRatio=8 意味着 Eden : (每个 Survivor) = 8 : 1,即两个 Survivor 合计只占新生代的 1/5(20%)。当短命对象创建速率高、但部分恰好存活过一次 Minor GC 时,它们会被复制进 Survivor 区——而这个区太小,很快被填满。一旦 Survivor 空间不足以容纳本轮 GC 的存活对象,JVM 就会尝试把“溢出”的对象直接晋升老年代;若此时老年代剩余空间不足或碎片化严重,就触发 promotion failed,进而强制触发 Full GC(尤其是 CMS 下会立即启动并发收集)。
关键点在于:这不是老年代本身满了,而是“晋升通道”被堵住了——Survivor 区太小 + 老年代没预留足够担保空间,双重挤压导致失败。
如何用 -XX:SurvivorRatio 缓解晋升压力
目标不是盲目调大 Survivor,而是让 Survivor 区能容纳住「典型生命周期为 1~2 次 GC」的对象总量。实操中建议:
- 先用
jstat -gc <pid> 1000观察S0U/S1U是否长期 >90%,且EU(Eden 使用率)频繁打满 → 这是 Survivor 不足的强信号 - 压测时关注每次 Minor GC 后晋升到老年代的字节数(GC 日志中的
PSYoungGen行末的->后数值),若单次晋升量常超 10MB,说明 Survivor 容量与对象分布不匹配 - 将
-XX:SurvivorRatio从 8 改为 4 或 3:例如-Xmn2g -XX:SurvivorRatio=4,此时 Eden 占 1.33g,每个 Survivor 约 333MB(原为 200MB),空间翻倍可显著降低溢出概率 - 必须配合
-Xmn固定新生代大小,否则 JVM 动态调整会抵消 SurvivorRatio 的效果
容易踩的坑:SurvivorRatio 调太大反而有害
-XX:SurvivorRatio 不是越大越好。Survivor 区过大,意味着 Eden 区被压缩,Minor GC 频率会上升——因为 Eden 更快填满,而多数对象其实活不过第一次 GC。高频 Minor GC 本身就会增加 STW 时间和 CPU 开销。
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
更隐蔽的风险是:当 Survivor 区远大于实际所需,对象在其中“滞留”时间变长,可能因年龄计数器累积更快达到 -XX:MaxTenuringThreshold,反向加速晋升。所以调整后务必验证:
- GC 日志中
Desired survivor size是否稳定在合理范围(比如 100MB~500MB),而不是动辄上 G - 使用
-XX:+PrintTenuringDistribution查看每轮 GC 后各年龄对象大小分布,确认没有大量 age=1 对象堆积在 Survivor 里“等晋升” - 避免
-XX:SurvivorRatio=2这类极端值——它让 Eden 仅占新生代 1/2,通常得不偿失
必须同步检查的老年代配套参数
只调 -XX:SurvivorRatio 不够。Promotion Failed 的另一半原因是老年代“接不住”。以下参数必须联动审视:
-
-XX:CMSInitiatingOccupancyFraction:CMS 触发阈值。若设为 80,但老年代实际可用空间 (Xmx - Xmn) * (1 - CMSInitiatingOccupancyFraction/100) >= Xmn / SurvivorRatio * 2 -
-XX:+HandlePromotionFailure:JDK 7u4 以后默认开启,但某些旧版本需显式启用,否则遇到 Survivor 溢出直接退化为 Full GC - 禁用
-XX:TargetSurvivorRatio=100:该参数试图让 Survivor 利用率逼近 100%,反而放大溢出风险,生产环境应保持默认(50)或设为 60~70
真正卡住 Promotion Failed 的,从来不是单一参数,而是 Eden、Survivor、老年代三者容量与对象生命周期之间的动态平衡。调参前看 GC 日志,调参后盯晋升量和老年代碎片,比背参数值重要得多。

















