这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」
前言
以上这篇文章中有说过如何判断对象是否为垃圾,但是回收的话还需要一些回收的算法。
常见的回收算法有以下四种:
1、标记清除算法
2、标记整理算法
3、标记复制算法
4、分代回收算法(此篇不讲)
标记清除算法
标记清除算法是最早出现的也是最基础的垃圾收集算法,该算法于1960年由Lisp之父John McCarthy提出。
该算法可以分为两个阶段:1、标记 2、清除
标记
通过上图我们认为与 GC ROOT 没有关联的对象就标记为垃圾。
清除
把刚才标记的对象内存释放出来,然后放入空闲内存列表中,下次我们需要创建对象的时候就从空闲内存列表中进行使用。
小结
该算法是最基础的收集算法,后续的收集算法很多都是以该算法为基础,并对其算法的缺点进行改进而得到的。主要有以下两个缺点:
1、执行的效率极不稳定,当堆中有大量需要回收的对象这时候就需要做大量的标记和清除操作,标记和清除的执行效率随数量的增长而降低。 2、内存空间碎片化问题,标记、清除操作完之后会产生大量的不连续内存碎片,从而导致当程序中需要分配较大对象的时候无法找到足够的连续内存而不得不提前触发再一次垃圾收集动作。
标记整理算法
标记整理算法的主要分为两个阶段:1、标记 2、整理
标记
该阶段和标记清除算法的第一个阶段是一样的。
整理
阶段主要是解决标记清除算法出现的内存空间碎片化的问题,在清除垃圾的时候把内存整理好。
小结
标记整理算法在整理的过程中需要牵扯到对象的内存移动,必然这个效率肯定会比较低。
标记复制算法
标记复制算法简称为复制算法,为了解决标记清除算法面对大量对象需要回收时执行效率低的问题,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着 的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
标记
标记清除算法一样,与 GC ROOT 没有关联的对象就标记为垃圾。
复制回收
把不需要回收的对象复制到另一部分空闲的内存中,那么之前的那一块内存就都是垃圾,把之前整块都清空,然后交换位置,下次进行回收的时候进行同样的操作。