标记-整理算法压缩阶段通过计算存活对象新地址写入forwarding指针、更新所有引用、最后按新地址移动对象三步消除碎片。Lisp2算法需三次遍历,移动对象开销大,但分配只需bumppointer,速度飞快。
标记-整理算法压缩阶段的核心目标是消除内存碎片,通过三步严格序贯操作实现:先计算存活对象新地址并写入forwarding指针,再更新所有引用指向新地址,最后按新地址移动对象数据。

标记-整理算法的压缩阶段,本质上是将内存中的碎片彻底清理干净——不仅清除垃圾对象,还要将所有存活对象如同搬家一般,整齐地排列到堆的一端,从而腾出一大块连续的空闲空间。这一过程看似简单,实际操作却涉及对象移动、地址重算和引用更新三重操作,必须严格遵循顺序,否则会导致混乱。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
压缩操作不能直接移动对象,必须按以下顺序执行,否则可能引发数据错乱:
因为压缩是在原堆空间内完成的(不依赖额外半区)。如果先移动对象,而某些引用仍指向旧地址,就会读到被覆盖的脏数据,或者导致对象被重复移动。forwarding指针的设计正是为了将“定位置”和“搬东西”这两个步骤解耦——它让引用更新有据可查,也让移动操作可以安全地推迟执行。
Lisp2 是最经典的标记-压缩实现,其结构清晰体现了上述逻辑:
该算法不要求对象大小一致,适用于通用JVM堆,但代价是需要三次遍历,停顿时间相对较高。
压缩之后,堆空间会形成“存活区 + 空闲区”的整齐格局:
因此,CMS选择放弃压缩,而G1采用分区加局部压缩的策略来寻求折中——毕竟在性能和延迟之间,需要找到合适的平衡点。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述