垃圾回收器在回收垃圾以前第一件事就是判断哪些是能够被回收的对象,如何判断呢?咱们能够根据该对象是否还有引用指向它来进行判断,若是有则不能回收,若是没有则能够回收,具体有如下几种算法:java
- 引用计数算法:
给对象添加一个引用计数器,每当它被引用一次计数器就加一,当该引用失效时就减一,若是计数器的值为0就表示它要被垃圾收集器做为垃圾收集了。这种算法存在一个问题,就是若是对象之间互相循环引用,他们就不可能被垃圾回收。
举个栗子:
public class RefrenceCounting {
public Object instance = null;
}
public class TestGc {
public static void main(String[] args) {
RefrenceCounting rf1 = new RefrenceCounting();
RefrenceCounting rf2 = new RefrenceCounting();
rf1.instance = rf2;
rf2.instance = rf1;
rf1 = null;
rf2 = null;
System.gc();
}
}
从图中能够看到,rf1和rf2互相引用,即便rf1和rf2置空,从外界没法访问他们,可是他们的引用计数器不为空,垃圾收集器没法回收他们。算法
- 可达性分析算法:
经过一系列称为“GC Roots”的对象做为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到Gc roots没有任何引用链相连时则此对象是不可用的。
上图中obj1,obj2,obj3都有引用指向Gc Roots,obj4和obj5没有指向Gc Roots的引用,因此他们会做为垃圾回收器的对象。可达性分析算法是java中使用的算法。
能够做为Gc Roots的对象包括如下几种:
1) 虚拟机栈(栈帧中的本地变量表)中引用的对象
2) 方法区中类静态属性引用的对象
3) 方法区中常量引用的对象
4) 本地方法栈中引用的对象ide
引用计数算法和可达性分析算法都和引用有关,在jdk1.2之后引用被分为四种:对象
- 强引用:强引用就是例如 ObjectA a = new ObjectA(),这样的引用,存在这种引用的对象不会被垃圾回收器回收。2:软引用:软引用是指一些引用还有用但并不是必须,被软引用的对象会在内存被占满,即将发生内存溢出异常以前进行回收。3:弱引用:被弱引用的对象只能生存到下一次垃圾回收发生以前,当下一次垃圾回收时,不管内存是否被占满都会回收弱引用的对象。4:虚引用,被虚引用的对象和没有被引用的对象同样都会被垃圾回收器回收,不一样的是,它在被回收时会收到一个系统通知。