标记-清除适合老年代因stw短且不移动对象,但碎片化易致oom;复制算法适配新生代高死亡率,以空间换高效回收;标记-整理通过移动对象消除碎片,但stw长,是老年代兜底方案。

面试问GC算法,重点不是背定义,而是讲清楚“为什么这么设计”——每种算法背后都有明确的工程取舍:空间换时间、碎片换吞吐、停顿换连续性。真正拉开差距的,是能不能结合内存分布特征和实际运行压力,说出哪块该用什么算法、为什么不能乱换。
标记-清除:老年代的妥协选择
它不移动对象,只打标+清空,所以STW时间短、适合大对象密集的老年代。CMS收集器就靠它实现低延迟,但代价是碎片化——当连续大对象(比如缓存数组、长文本)频繁分配时,容易触发Concurrent Mode Failure,直接退化成Serial Old的标记-整理。面试时如果被问“CMS为什么被弃用”,可以点出:它依赖标记-清除,而碎片积累后无法避免full GC,且无法处理浮动垃圾。
复制算法:新生代的效率优先策略
新生代对象90%以上朝生夕死,复制成本极低。关键不在“两块内存”,而在实际落地时的优化:Eden:S0:S1 = 8:1:1,只预留10%空间做复制缓冲,大幅缓解50%浪费问题。ParNew和G1的Young GC都沿用这一逻辑——不是简单搬数据,而是借“存活率低”这个事实,把GC变成一次高速内存重排。如果被问“为什么不用标记-整理”,直接答:移动大量对象开销远高于复制,且新生代本就不需要长期连续空间。
标记-整理:老年代的兜底方案
当碎片已影响分配,或使用Serial Old、Parallel Old这类吞吐优先收集器时,必须压缩内存。它比标记-清除多一个“滑动整理”步骤,所有存活对象向一端靠拢,腾出大片连续空间。代价是STW更长——因为要更新所有对象引用地址。G1在Mixed GC阶段也会局部整理Region,但不会全堆扫描,这是它区别于传统标记-整理的关键工程改进。
分代回收不是算法,是调度框架
现代JVM从不单独用某一种算法,而是按区域动态组合:新生代默认复制,老年代根据收集器选标记-清除(CMS)或标记-整理(ZGC前的Serial Old)。面试时提到G1或ZGC,要强调它们打破了分代物理界限,但依然遵循“年轻对象快收、老对象少动”的工程直觉——G1用Remembered Set加速跨代引用扫描,ZGC用染色指针+读屏障实现并发标记,底层逻辑没变,只是把停顿切得更细。











