虚拟机是如何判断一个对象是否可以被回收?主要是使用以下两种方法。
引用计数器算法
给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器值为0的对象就是不可能再被使用的。
优点:实现简单,判定效率高。
缺点:难以解决对象之间互相循环引用的问题。
可达性分析算法
通过一系列成为 GC Root 的对象作为起点,从这些节点开始往下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Root 没有任何引用链相连时,则证明此对象是可以被回收的。当前 HotSpot 虚拟机就是使用的这个算法。
在Java语言中,可作为 GC Root 的对象包括以下几种:
- 虚拟机栈中引用的对象。
- 方法区中类静态属性引用的对象。
- 方法区中常量引用的对象。
- 本地方法栈中 JNI 引用的对象
从 Java1.2 开始 Java 引用分为以下四种:
- 强引用:在程序代码之中普遍存在的,类似 Object obj = new Object() 这类的引用。只要强引用还在,垃圾收集器永远不会回收掉被引用的对象。
- 软引用:用来描述一些还有用但非必须的对象。对于软引用关联的对象,在系统将要发生溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。JDK1.2后使用 SoftReference 类来实现软引用。
例如:SoftReference