Java新生代划分为Eden、S0、S1是为了实现高效复制算法:对象优先分配在Eden区,Minor GC时将Eden和当前Survivor(如S0)的存活对象复制到另一Survivor(如S1),清空源区并交换角色,避免碎片且提升回收效率。

Java 新生代内存中,Eden 区和两个 Survivor 区(S0 和 S1)通过“复制算法”协同工作,核心目标是高效分配对象、快速回收短命对象,并减少内存碎片。
对象优先在 Eden 区分配
绝大多数新创建的对象会直接分配到 Eden 区。这是因为 Eden 是新生代中最大的一块连续空间,分配效率高(只需移动指针,即“指针碰撞”方式)。
- 如果 Eden 空间足够,对象顺利分配,JVM 不触发 GC;
- 如果 Eden 满了但老年代还有空间,JVM 会触发一次 Minor GC;
- 分配失败且无法扩容(如 JVM 启动参数已固定堆大小),可能直接抛出 java.lang.OutOfMemoryError: Java heap space。
Minor GC 时对象如何在 Survivor 区之间流转
当 Eden 区满触发 Minor GC,JVM 会把 Eden 中仍存活的对象,连同其中一个 Survivor 区(比如 S0)中还存活的对象,一起复制到另一个空的 Survivor 区(比如 S1)。复制完成后:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- Eden 区清空;
- S0(原存活区)被清空;
- S1 成为新的“目标 Survivor 区”,存放本轮所有存活对象;
- 每个对象在 Survivor 区每经历一次复制,年龄(age)加 1;
- 默认 age ≥ 15 的对象,在下一次 GC 时晋升到老年代(可通过 -XX:MaxTenuringThreshold 调整)。
Survivor 区容量不够怎么办?
如果复制过程中,目标 Survivor 区(如 S1)空间不足,无法容纳所有存活对象:
- JVM 会将部分年龄较大或“挤不进”的对象直接提前晋升到老年代;
- 这种晋升叫“担保机制(Handle Promotion)”,不是错误,但频繁发生可能预示 Survivor 设置过小或对象生命周期偏长;
- 可通过 -XX:SurvivorRatio=N 调整 Eden 与单个 Survivor 的比例(如 -XX:SurvivorRatio=8 表示 Eden:S0:S1 = 8:1:1)。
为什么需要两个 Survivor 区?
双 Survivor 设计是为了避免“半满复制”导致的反复拷贝和空间浪费:
- 只用一个 Survivor 区的话,每次 GC 都需判断哪些对象该保留、哪些该丢弃,容易产生碎片且复制逻辑复杂;
- 两个 Survivor 区交替使用,始终保证有一个是空的,复制过程简单、无碎片、GC 停顿更可控;
- 本质是“复制算法”的标准实现:From Space → To Space,角色每次 GC 后互换。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










