标记-清扫回收地开销较低,但其可能受到内存碎片问题地困扰。在一个设计良好地系统中,垃圾回收通常只会占用整体执行时间地一小部分,赋值器地执行开销将决定整个程序的性能,因此应当设法降低赋值器的开销,特别是应当尽量提升它的分配速度。标记-整理回收器可以根除碎片问题,而且支持极为快速的“阶跃指针”分配,但它需要多次堆遍历过程,进而显著增加了回收时间。
半区复制算法:
该算法属于追踪式回收算法。回收器在复制过程中会进行堆整理,从而可以提升赋值器的分配速度,且回收过程只需对存活对象遍历一次。其最大的缺点在于堆的可用空间降低了一半。
1.半区复制回收
基本的复制式回收器会将堆划分为两个大小相等的半区,分别是来源空间和目标空间。当堆空间足够时,在目标空间中分配新对象的方法是根据对象大小简单地增加空闲指针,如果可用空间不足,则进行垃圾回收。回收器在将存活对象从来源空间复制到目标空间之前,必须先将两个半区的角色互换。在回收过程中,回收器简单地将存活对象从来源空间中迁出;在回收完成后,所有存活对象将紧密排布在目标空间地一端。在下一轮回收之前,回收器将简单地丢弃来源空间(以及其中的对象),但在实际应用中基于安全考虑,许多回收器在初始化下轮回收过程之前都会先将该区域清零。
与标记-整理回收不同,半区复制回收无须在对象头部引入额外空间。由于来源空间中的对象在复制完成后便不再使用,所以其每个槽都可以用于记录转发地址(至少在万物静止式回收中如此)。因此复制式回收甚至适用于不包含头部的对象。
2.遍历顺序与局部性
赋值器和回收器的局部性对程序性能有重要影响。如果