复制算法专用于新生代,因其98%对象朝生夕死,仅需复制少量存活对象,避免碎片、单次扫描、stw时间短;老年代存活率高,复制成本过高故不适用。

复制算法是 Minor GC 高效运行的核心支撑,它专为“朝生夕死”的新生代对象设计,用空间换时间,避免碎片、简化回收逻辑。
为什么复制算法只用于年轻代
新生代中约 98% 的对象存活时间极短,一次 Minor GC 后能活下来的对象很少。复制算法只需搬运少量存活对象,清空原区域即可释放大量空间,效率远高于扫描整个内存的标记清除或整理算法。而老年代对象存活率高、空间大,若强行复制,需额外预留同等大小空闲内存,成本过高且不现实。
Minor GC 中复制算法的实际执行流程
- 每次 GC 时,JVM 将 Eden 区 + 当前 From Survivor 区中所有存活对象,统一复制到 To Survivor 区(或直接晋升至老年代)
- 复制过程中同步更新对象年龄:每经历一次 Minor GC,年龄 +1;达默认阈值(15)即晋升
- 若 To Survivor 区空间不足,剩余存活对象直接进入老年代(称为“担保失败”或“分配担保”)
- 复制完成后,Eden 和 From Survivor 区被整体清空,无需逐个判断和清理
- 最后交换 From/To 角色,确保下一轮有干净的接收区
复制算法带来的关键优势
- 无内存碎片:复制后目标区连续紧凑,新对象可按顺序快速分配,避免频繁查找空闲块
- 单次扫描完成回收:仅需遍历一次存活对象,不需像标记-清除那样扫描两次(标记+清除)
- STW 时间可控:因处理数据量小、逻辑简单,停顿通常在毫秒级,对响应敏感型服务影响小
- 天然支持对象晋升机制:年龄计数与复制动作耦合,晋升决策在搬运时一并完成,无需额外步骤
需要注意的边界情况
当 Survivor 区太小或对象分配速率过高,会导致大量对象无法存入 Survivor 而直接进入老年代——这会加速老年代填满,间接诱发 Full GC。因此,-XX:SurvivorRatio 和 -Xmn 的合理设置,本质是在为复制算法创造稳定运行条件。










