这是我参与8月更文挑战的第4天
上文介绍了分代收集理论,基于这三条理论,衍生出了内存回收不同算法,接下来分别介绍这三种算法。
一、标记-清除算法
最早出现也是最基础的垃圾收集算法是“标记-清楚”算法。
分为两个阶段:
首先标记出所有需要回收的对象,在标记完成后,统一回掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。标记过程就是判断对象是否属于垃圾的判定过程(gc roots 和计数器引用)。
缺点: 当大部分对象都需要回收时,此算法效率低下
二、标记-复制算法
标记-复制算法常被称为“半区复制”。主要是为了解决标记-清除算法中效率低下的问题。半区复制: 将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块内存使用完了,就讲还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次性清除掉。
缺点: 将可用内存缩小一半,空间浪费严重。
IBM曾对新生代“朝生熄灭”的特点做了更量化的诠释---新生代的对象有98%熬不过第一轮回收,因此并不需要1:1的比例来划分内存空间。
Appel式回收: 将内存分为一块较大的Eden空间和两块较小的Survivor空间,默认比8:1,每次使用Eden和一块Survivor空间,只有10%空间是浪费的。
但是任何人都无法确保每次回收时只有不多余10%的对象存活,因此Apple式回收还有一个罕见情况“逃生门”的设计。当Survivor空间无法容纳一次新生代回收之后存活的对象时,这些对象就会通过分配担保机制直接进入老年代。
三、标记-整理算法
过程和标记-清除算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都像内存空间一端移动,然后直接清理掉边界以外的内存。
是否移动对象都存在弊端,移动则内存回收时更复杂,不移动则内存分配时更复杂。
与标记-清除算法的区别:整理关注吞吐量,清除关注延迟