这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战
1. 前言
目前来说,当前虚拟机主要采用了四种垃圾回收算法,分别是 标记 - 清除算法、标记 - 复制算反、标记 - 整理算法;虚拟机为了提高内存回收的效率,将 JVM 分成不同的区域,对不同的区域采用不同的垃圾回收算法,这就是分代收集算法的思想。
本文主要对三种收集算法做一个介绍
2. 标记 - 清除算法
该算法分为两个阶段,标记出所有需要回收的对象,标记结束后统一回收。这个算法很容易理解,也很简单,后面的算法都是根据该算法的基础加以改进而来。
不足的方面就是标记和清除的效率比较低下。且这种做法会让内存中的碎片非常多。这个导致了如果我们需要使用到较大的内存块时,比如一个大对象进来的时候,就无法分配到足够的连续内存了。
3. 标记 - 复制算法
为了解决效率问题,“标记-复制”收集算法出现了;它将内存模块分为了两部分,不管怎样都只使用其中的一块。
当被使用的这块内存快要满了,就将那些还存活的对象标记出来,然后移动到另一块没有被使用的区域中,再一次性把整个内存区域清空,即每次回收都是对一半的内存区域进行回收。
虽然标记 - 复制算法解决了内存碎片的问题,但是同样的也带来了内存缩水、空间使用率低下的问题
3. 标记 - 整理算法
根据老年代的特点提出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存
对于老年代来说,对象存活率较高,而且找不到其他内存进行分配担保,所以老年代不能选用标记 - 复制算法。
4. 分代收集算法
说白了,为了更好更快的分配内存,当前的 JVM 基本都采用了分代收集算法的机制,其实这不是一种全新的算法,而是将 JVM 的内存区域划分为若干有不同特性的区域,再针对这些不同的区域采用不同的垃圾回收算法。
比如在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。