本文主要讨论可达性算法
GC(Garbage Collection)需要考虑三件事:
1. 哪些内存需要回收?
2. 什么时候回收?
3. 如何回收?
确定哪些内存被回收
1.1 可达性算法
首先我们考虑第一个问题,哪些内存需要被回收?最初有一个引用计数法,当一个对象的引用计数为0的时候则表示该对象需要被回收了,但是这个存在一个循环引用的问题,如下图objA和objB互为引用,但是二者都属于无用的对象,此时引用计数都不为0,无法回收。所以现在大部分都是可达性分析法,下面对此方法做一个简单说明:
算法通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连,证明此对象不可用。如图object5,6,7与GC root没有连接,属于不可用对象
GC Roots主要包括以下几种:
- 虚拟机栈中的引用对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(Native)引用的对象
1.2 再谈引用
JDK1.2之后,JAVA对引用概念进行了扩充,将引用分为强引用(strong)、软引用(soft)、弱引用(weak)、虚引用(phantom)
强引用:传统引用
软引用:系统发生内存溢出之前,将会把这些对象列进回收范围之内进行第二次回收。
弱引用:只生存到下一次GC之前
虚引用:也称为幽灵引用或者幻影引用。无法通过虚引用获得对象实例,唯一作用就是能在对象被收集器回收时收到一个系统通知。