垃圾回收算法知识整理

垃圾回收的作用区域

垃圾回收主要针对的是:

  • 方法区
  • 堆内存

其中堆是垃圾收集器的工作重点。

垃圾回收的阶段

标记阶段

引用计数

如果对象被引用了就将引用计数器+1,当引用失效的时候再-1即可。只要当引用计数器为0,就代表此对象可以被回收了。

注:Python 主要使用引用计数法进行 GC 而 JAVA 没有使用此种方案。

可达性分析

如果对象与根对象的集合(GC Roots)存在直接或间接关系则证明对象不可回收。

在 Java 中 GC Roots 包含以下几类元素:

  • 虚拟机栈中引用的对象
  • 本地方法栈内引用的对象
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被 synchronized 持有的对象
  • Java 虚拟机内部的引用
  • 反应 Java 虚拟机内部情况的 JMXBean,JVMTI 中注册的回调、本地代码缓存等

清除阶段

标记清除算法

当堆中的有效内存空间被耗尽的时候,就会停止程序(Stop The World) 然后进行标记和清除操作。

  • 标记操作

由回收器从根节点开始遍历并标记所有被引用的对象。

  • 清除操作

由回收器对堆内存从头到尾进行遍历,如果发现对象未被标记则将其地址存储在空闲地址列表中。

复制算法

将内存空间分为两份,每次仅使用其中一份。当垃圾回收的时候将存活的对象复制到未被使用的另一 份内存中,然后清除正在使用的所有对象。在执行完成后交换两个内存的角色,最后完成垃圾回收。

注:新生代的垃圾回收算法。

标记压缩算法

标记压缩算法和标记清除算法类似第一阶段都会从根节点开始标记所有的应用对象, 而在第二阶段则会把所有的存活对象压缩到内存的一端并按顺序排放。之后再去清理外界空间。

注:老年代的垃圾回收算法。

针对 STW 缺陷的弥补方案

增量收集算法

在处理的时候通过切换垃圾回收线程和应用程序线程的交替执行的方式来实现内存回收。

分区算法

将内存区分成多块,然后根据目标的停顿时间,每次合理的回收若干个小区间来减少停顿。


垃圾回收算法知识整理
https://wangqian0306.github.io/2020/gc/
作者
WangQian
发布于
2020年6月17日
许可协议