垃圾回收算法

垃圾回收算法

可达性分析法

通过一系列的称为 GC Roots 的对象作为起点,然后向下搜索;搜索所走过的路径称为引用链/Reference Chain, 当一个对象到 GC Roots没有任何引用链相连时,即该对象不可达,也就说明此对象是不可用的 在Java, 可作为GC Roots的对象包括:

  1. 方法区: 类静态属性引用的对象
  2. 方法区: 常量引用的对象
  3. 虚拟机栈(本地变量表)中引用的对象
  4. 本地方法栈JNI(Native方法)中引用的对象

引用计数法

引用计数法是最经典的一种垃圾回收算法。其实现很简单,对于一个A对象,只要有任何一个对象引用了A,则A的引用计算器就加1,当引用失效时,引用计数器减1。只要A的引用计数器值为0,则对象A就不可能再被使用。虽然其思想实现都很简单(为每一个对象配备一个整型的计数器),但是该算法却存在两个严重的问题:

  1. 无法处理循环引用的问题,因此在Java的垃圾回收器中,没有使用该算法。
  2. 引用计数器要求在每次因引用产生和消除的时候,需要伴随一个加法操作和减法操作,对系统性能会有一定的影响。

上述两种算法都是解约哪些要回收,下面的为如何回收的算法。 垃圾回收主要回收的是堆内存,基于分代的思想: 分别为新生代和老年代

标记清除法

该算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象, 在标记完成后统一清理掉所有被标记的对象.

缺点:

  1. 效率问题: 标记和清除过程的效率 都不高;
  2. 空间问题: 标记清除后会产生大量 不连续的内存碎片, 空间碎片太多 可能会导致在运行过程中需要分配 较大对象时无法找到足够的连续内 存而不得不提前触发另一次垃圾收集.

复制算法

该算法的核心是将可用内存按容量划分为大小相等的两块, 每次只用其中一块, 当 这一块的内存用完, 就将还存活的对象复制到另外一块上面, 然后把已使用过的内存空 间一次清理掉.

优点:

  1. 由于是每次都对整个半区进行内存回收,内存分配时不必考虑内存碎片问题。
  2. 垃圾回收后空间连续,只要移动堆顶指针,按顺序分配内存即可;
  3. 特别适合java朝生夕死的对象特点

缺点:

  1. 内存减少为原来的一半,太浪费了;
  2. 对象存活率较高的时候就要执行较多的复制操作,效率变低;
  3. 如果不使用50%的对分策略,老年代需要考虑的空间担保策略

标记整理算法

该算法首先标记出所有需要回收的对象, 在标记完成后让所有存活的对象都向一端移动,然后清理掉端边界以外的内存

优点

  1. 不会损失50%的空间;
  2. 垃圾回收后空间连续,只要移动堆顶指针,按顺序分配内存即可;
  3. 比较适合有大量存活对象的垃圾回收;

缺点 1.标记/整理算法唯一的缺点就是效率 也不高,不仅要标记所有存活对象, 还要整理所有存活对象的引用地址。 从效率上来说,标记/整理算法要低于复制算法。

垃圾回收算法


分享到:


相關文章: