首先,最基础的GC算法有三个:
- 标记/清除算法:通过GC Root对象进行遍历,对从GC Root对象可达的对象都加一个标记,即标记其为可达对象,然后再对堆内存进行遍历,如果一个对象没有该标记,那就直接从堆内存中回收这个对象。
- 复制算法:把内存分成两个部分,使用其中一块,当这一块内存使用完,需要GC的时候,就把还存活的对象复制到另一块内存中,然后把前面那一块内存全部清除。
- 标记/整理算法:通过GC Root对象进行遍历,对从GC Root对象可达的对象都加一个标记,即标记其为可达对象,然后将所有存活对象都整理到一端,将端线另一边的对象(即死亡对象)清除。
比较:标记清除算法:缺点:清除的时候要遍历堆内存,效率低;内存碎片大,为新的对象(大对象)分配内存空间时容易引起新一轮GC
复制算法:优点:比标记清楚效率高。缺点:内存需要分区,代价太高;如果对象存活率高(甚至为100%)那么意味着所有的对象都要复制一边到另一半内存,效率低。
标记整理算法:优点:没有空间碎片,也不需要分区。缺点:需要标记还需要整理对象的地址,效率不如复制算法。
综合上述优点产生了:分代收集算法
首先将内存按照对象存活的时间周期分为:新生代(对象很快死亡),老年代(长期存活的对象),永久代(HotSpot特有,一般不进行GC,这里不讨论)
新生代:复制算法,因为存活下来的对象少,所以复制的对象也少,效率就高了
老年代:标记清除或标记整理,因为有很多对象长期存活,用复制算法效率低下,而且老年代也没有额外的内存区域
参考自:https://www.jianshu.com/p/76959115d486