Java 对象有 4 种引用方式,分别是强引用,软引用,弱引用,虚引用,这四种引用强度依次减弱。
强引用
强引用是最常见的,一个变量用等号赋值,就是把这个变量指向强引用。只要有强引用,GC 永远不会回收掉该对象。
软引用
软引用引用的对象,虽然是可达的(存活的),但是在 GC 回收的时候,会考量这些对象。当 GC 认为内存还足够,那么就不回收这些对象了,但是当 GC 认为内存紧缺不够的时候,会强行回收这些对象。
软引用需要借助 SoftReference 类来实现,下面的代码创建了一个软引用,并使用它。
SoftReference<String>sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
弱引用
弱引用和软引用类似,对象都是可达的,但仍然会被 GC 回收。不同点在于,弱引用只要 GC 开始,就会被回收,而软引用只有当 JVM 内存空间不足的时候才会被回收。
弱引用的需要 WeakReference 类来实现。
WeakReference<String>sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(sr.get());
第二个输出结果是 null,这说明只要 JVM 进行垃圾回收,被弱引用关联的对象必定会被回收掉。
虚引用
虚引用也称为幽灵引用或幻影引用。虚引用的 get 方法永远返回 null,一个对象是否存在虚引用不会对生存时间构成影响。唯一的用处:能在对象被 GC 时能够得知。JAVA 中用 PhantomReference 来实现虚引用。PhantomReference 使用时,必须要关联一个 ReferenceQueue 对象。当一个对象被 GC 的时候,如果该对象有虚引用,那么就会把对象放入 ReferenceQueue 里。通过检查 ReferenceQueue 队列中的对象来判等对象是否即将被回收,可以记录一些日志之类的信息。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String>pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
图片来源于网络