Survivor区是新生代中用于对象年龄管理与复制的缓冲区域,通过年龄晋升机制(默认15次)和动态年龄判定,协助JVM精准筛选长期存活对象并减少老年代污染。

Survivor 区是 JVM 堆中新生代(Young Generation)的一部分,与 Eden 区共同构成 Minor GC 的主要工作区域。它不直接“回收”对象,而是通过“年龄晋升机制”和“对象复制策略”,协助 JVM 更高效、更精准地识别和清理短生命周期对象,同时减少老年代过早污染。
Survivor 区的核心作用:对象年龄管理
每次 Minor GC 时,Eden 区中存活的对象会被复制到一个 Survivor 区(比如 S0),同时年龄设为 1;已在 Survivor 区的对象,若再次存活,则年龄 +1。JVM 用这个年龄值判断是否该晋升到老年代——默认达到 15(可通过 -XX:MaxTenuringThreshold 调整)就进入老年代。
- 避免刚“活下来”的对象立刻进老年代,防止老年代被大量临时对象占满
- 年龄计数只在 Survivor 区间复制时更新,Eden → Survivor 算第一次,之后每经历一次 Minor GC 且存活,就加 1
- 如果某次 GC 后,某个年龄的对象总大小 > 当前 Survivor 空间的一半,JVM 会把所有 ≥ 该年龄的对象提前晋升(动态年龄判定)
两个 Survivor 区如何协作:From 和 To 的角色切换
新生代通常配置两个大小相等的 Survivor 区(S0 和 S1),同一时刻只用其中一个作为“目标”(To),另一个作为“来源”(From)。Minor GC 时:
- Eden 区 + 当前 From 区中存活的对象,统一复制到 To 区
- 复制完成后,From 和 To 角色互换(即清空原 To,让它变成下一轮的 From)
- 这种设计避免了内存碎片——复制算法天然保证 To 区内对象连续存放
注意:不是所有存活对象都一定进 Survivor;大对象可能直接分配到老年代(取决于 -XX:PretenureSizeThreshold),而 Survivor 空间不足时,多余对象也会直接晋升。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
Survivor 区如何降低 GC 压力
它本质是给对象“多一次验证机会”,让真正稳定的对象浮出水面,从而优化整体回收节奏:
- 过滤掉“偶然存活”的临时对象(比如方法内创建又很快不再引用的中间对象)
- 减少老年代 GC 频率:没有 Survivor 区,Eden 中每次存活的对象都会直奔老年代,很快触发 Full GC
- 配合可达性分析,让 GC Roots 扫描范围更聚焦于 Eden + 一个 Survivor,提升 Minor GC 速度
调优提示:别盲目增大 Survivor
Survivor 太小,会导致对象频繁提前晋升(年龄没到就因空间不够而进老年代);太大又浪费新生代空间,延长 Minor GC 周期,单次耗时可能上升。
- 观察 GC 日志中的 Desired survivor size 和实际晋升量,用 -XX:SurvivorRatio(如 -XX:SurvivorRatio=8 表示 Eden:S0:S1 = 8:1:1)调整比例
- 用 -XX:+PrintGCDetails 查看每次 GC 后各区域大小及晋升对象大小,判断是否合理
- 多数应用保持默认比例即可;高并发短生命周期场景可适当调小 SurvivorRatio(即增大 Survivor),但需实测验证

















