简单谈谈引用(摘自java虚拟机第二版 )
署名:逆水
四种引用
引用介绍及回收时机
一、四种引用
在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这4种引用强度依次逐渐减弱。
二、引用介绍及回收时机
1.强引用 >>> 就是指在程序代码之中普遍存在的,类似“Object obj=new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码:
public class Test {
public static void main(String[] args) {
new Test ().f1();
}
public void f1() {
Object object = new Object();
Object[] objArr = new Object[99999999];
}
}
当运行至Object[] objArr = new Object[99999999];这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是,当f1运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。
2.软引用 >>> 是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。在JDK 1.2之后,提供了java.lang.ref.SoftReference类来实现软引用。
3.弱引用 >>> 也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。(ThreadLocal采用的就是弱引用,可以自行研究)
使用示例:
public class Test {
public static void main(String[] args) {
WeakReference<Object> wf = new WeakReference<Object>(new Object());
System.out.println(wf.get());
System.gc();
System.out.println(wf.get());
}
}
输出结果如下:
java.lang.Object@1b6d3586
null
4.虚引用 >>> 虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。