默认比例为8:1:1,即eden区占8份、每个survivor区各占1份;-xx:survivorratio=8表示eden与单个survivor区的容量比,双survivor区支持复制算法、避免碎片,比例失衡易引发对象过早晋升。

Eden区与Survivor区的默认比例是8:1:1
新生代堆空间默认划分为三部分:Eden区占8份,两个Survivor区(S0和S1)各占1份。也就是说,若新生代总大小为100MB,则Eden区为80MB,每个Survivor区为10MB。这个比例由JVM参数-XX:SurvivorRatio=8控制——该值表示Eden区与**单个**Survivor区的容量比,不是Eden与两个Survivor之和的比。
这个设计背后有明确目的:Eden区承担绝大多数新对象分配,而Survivor区只需容纳每次Minor GC后少量存活对象。过大的Survivor区会浪费空间;过小则容易导致“幸存对象无处可放”,被迫提前晋升到老年代,加剧老年代压力。
为什么要配两个Survivor区而不是一个?
双Survivor区(From/To)本质是为复制算法服务的内存结构保障:
- 每次Minor GC时,Eden + 当前From区的存活对象被统一复制到To区,同时年龄+1
- 复制完成后,Eden和From区被清空,To区变成新的From区,角色互换
- 若只有一个Survivor区,GC时需在原区域中“就地整理”或“覆盖写入”,必然产生内存碎片,且无法高效完成对象复制
- 双区机制保证了每次GC都有干净、连续的内存目标空间,避免碎片化,也简化了内存管理逻辑
调整SurvivorRatio的实际影响与适用场景
修改-XX:SurvivorRatio不能孤立进行,必须结合对象生命周期特征判断:
- 当应用短生命周期对象极多、但每次GC后存活率很低(如
- 当对象平均存活2–3次GC才进入老年代,且Survivor区频繁溢出(日志出现“to-space overflow”或大量提前晋升),说明Survivor太小,应减小SurvivorRatio(如设为6),增加Survivor容量
- 注意:Survivor区过大会降低Eden可用空间,反而可能增加Minor GC次数;过小会导致Promotion Failure风险上升,触发更昂贵的Full GC
配合使用的几个关键参数
仅调SurvivorRatio不够,还需关注对象晋升行为与空间协同:
- -XX:MaxTenuringThreshold:控制对象晋升老年代的年龄阈值,默认15。若观察到多数对象在第3~4次GC后才稳定,可设为4,避免长期滞留Survivor
- -Xmn:直接指定新生代大小。它比NewRatio更可控,尤其在堆总大小固定时,能避免因老年代波动导致新生代被动压缩
- -XX:+PrintGCDetails:必须开启,用于验证调整效果。重点关注每次Minor GC后Survivor占用率、晋升量(Promotion)、以及是否发生“Desired survivor size”警告











