标记-整理算法通过移动存活对象至内存一端并清空尾部空间,实现紧凑布局、避免碎片。先标记可达对象,再将其顺序迁移并更新引用,最后截断释放边界后空闲区,使分配只需指针推进。

标记-整理算法通过“移动存活对象 + 清理边界外空间”两步协同,强制让所有存活对象在内存中紧挨着排列,从而天然保证布局紧凑。
标记阶段:先锁定哪些对象必须保留
从 GC Roots(如栈中变量、静态字段、JNI 引用)出发,沿引用链遍历并标记所有可达对象。这一步不移动任何东西,只确保回收范围准确——未被标记的,就是可清理的垃圾。
整理阶段:把存活对象物理归拢到一端
这是实现紧凑布局的核心动作:
- 将所有已标记的存活对象,按顺序(常见为滑动顺序,保持原有相对位置)迁移至内存起始端(如低地址侧)
- 迁移过程中同步更新所有指向这些对象的引用:包括栈帧里的局部变量、其他对象的字段、寄存器中的指针等
- 迁移完成后,存活对象在内存中连续排列,中间不留空洞,形成一块“已用区”
清除阶段:一次性释放尾部整块空闲区
整理结束后,内存自然划分为清晰的两段:
- 前端是紧凑排列的存活对象
- 后端是从整理边界开始的、完全连续的大块空闲空间
- GC 直接清空该边界之后的所有区域,无需逐个扫描或拼凑碎片
为什么能避免碎片?关键在“移动+边界清零”
它不接受“留下空隙”的结果。标记-清除会留下离散空洞;复制算法虽紧凑但需预留一半空间;而标记-整理只占用实际所需内存,又通过强制归拢+边界截断,确保每次回收后都产出一个大而连续的空闲块——后续分配只需推进指针(bump-the-pointer),不再需要查找、合并或适配碎片。











