垃圾回收的算法有哪些
通过可达性分析算法,我们已经可以找到需要回收的对象。现在需要通过垃圾回收算法,把垃圾回收,释放内存。
1.标记清除算法(使用较少)
标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除。
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
可以看到,标记清除算法解决了引用计数算法中的循环引用的问题,没有从root 节点引用的对象都会被回收。
同样,标记清除算法也是有缺点的:
1.效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要 停止应用程序,对于交互性要求比较高的应用而言这个体验是非常差的。
2.(重要)通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于内存的各个角落,所以清理出来的内存是不连贯的。
导致的问题:我们知道数组也会存储到堆中,并且数组存储需要的是连续的内存空间。如果碎片化严重,就可能无法存储一个较大的数组!
2.复制算法
复制算法的核心就是,将原有的内存空间一分为二,每次只用其中的一块, 在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间 清空,交换两个内存的角色,完成垃圾的回收。
如果内存中的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该方式并且效率比较高,反之,则不适合。
1)将内存区域分成两部分,每次操作其中一个。
2)当进行垃圾回收时,将正在使用的内存区域中的存活对象移动到未使用的内 存区域。当移动完对这部分内存区域一次性清除。
3)周而复始。
优点: 在垃圾对象多的情况下,效率较高清理后,内存无碎片
缺点: 分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低
一般年轻代的垃圾回收器使用
3.标记整理算法
标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是 简单的直接清理可回收对象,而是将存活对象都向内存另一端移动,然后清理边 界以外的垃圾,从而解决了碎片化的问题。
1)标记垃圾。
2)需要清除向右边走,不需要清除的向左边走。
3)清除边界以外的垃圾。
优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多了一步,对象移动内存位置的步骤,其效率也有有一定的影响。
与复制算法对比:复制算法标记完就复制,但标记整理算法得等把所有存活对象 都标记完毕,再进行整理。
一般老年代的垃圾回收器使用