软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大的意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态,程序可以通过检查与虚引用关联的引用队列中是否已经包含指定的虚引用,从而了解虚引用所引用对象是否即将被回收。
引用队列由Java.lang.ref.ReferenceQueue类表示,它用于保存被回收后对象的引用。当把软引用,弱引用和引用队列联合使用时,系统回收被引用的对象之后,将会把被回收对象对应的引用添加到关联的引用队列中。与软引用和弱引用不同的是,虚引用在对象被释放之前,将把对应的虚引用添加到它的关联的引用队列中,这使得可以在对象被回收之前采取行动。
虚引用通过PhantomReference类实现,它完全类似于没有引用。虚引用对对象本身没有太大影响,对象甚至感觉不到虚引用的存在。如果一个对象只有一个虚引用,那它和没有引用的效果大致相同。
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceTest {
public static void main(String[] args) throws Exception{
Stringstr = new String("Java");
ReferenceQueue<String>rq = newReferenceQueue<String>();
PhantomReference<String>pr = newPhantomReference<String>(str,rq);
System.out.println(pr.get());
str = null;
System.out.println(pr.get());
System.gc();
System.runFinalization();
System.out.println(rq.poll());
System.out.println(rq.poll()==pr);
}
}
Output:
null
null
java.lang.ref.PhantomReference@61de33
false
使用这些引用类可以避免在程序只习惯期间将对象留在内存中。如果以软引用,弱引用或虚引用的方法引用对象,垃圾回收器就能够随意地释放对象。如果希望尽可能减小程序在其生命周期中所占用的内存大小,这些引用类就很有好处。最后需要指出的是:要使用这些特殊的引用类,就不能保留对对象的强引用,如果保留了就会浪费这些类所提供的任何好处。