Java垃圾回收

如何确定垃圾

Java 虚拟机内存中的程序计数器,虚拟机栈,本地方法栈这 3 个内存区域随线程而生,随线程而灭,是不需要过多考虑回收问题的。在 Java 堆里面存放着几乎所有的对象实例。垃圾回收器在回收之前,先要判断哪些对象是不能被任何途径使用的对象。

引用计数法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器就加 1,当引用失效的时候,计数器就减 1。在任何计数器为 0 的对象就是不可能在被使用的。

这样的算法实现简单,判定效率高。但是主流的 Java 虚拟机没有使用这样的算法来判断。因为这样的算法很难解决对象直线循环引用的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ReferenceCounting{
public Object instance = null;

public static void testGC(){
ReferenceCounting objA = new ReferenceCounting();
ReferenceCounting objb = new ReferenceCounting();
objA.instance = objB;
objB.instance = objA:

objA = null;
objB = null;
}
}

可达性分析算法

一般时时通过可达性算法来实现判断对象是否能被引用的。

算法基本思想是:通过一系列称为 “root” 的对象作为起点,从这个节点开始搜索,搜索走过的路径称为引用链 (Reference Chain),当一个对象不能通过饮用链到达 “root” 节点时,认为这个对象时不可达的。用图来说明,下面 object 5,object 6,object 7之间虽然相互之间有联系,但是是不可达的。

可达性图解

Java 中可作为 “root” 的对象包括以下几种:

  • 虚拟机栈(栈帧中本地变量表)中的引用对象
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 native 方法引用的对象

GC 算法

标记清楚算法

复制算法

标记整理算法

分代收集算法

Java 中四种引用类型