什么是虚引用?

  • Post category:Java

虚引用(Phantom Reference)是Java引用类型之一,它是四种引用类型中最弱的一种。虚引用主要用于在某一个对象被垃圾回收器回收时,收到一个系统通知。虚引用可以防止对象被回收时出现一些意料之外的情况,比如在对象被回收之前,需要执行某些清理操作,而这些清理操作在即将被回收的对象中无法执行。

虚引用本身并不能通过get()方法获取到被引用的对象,因此常常和引用队列(ReferenceQueue)一起使用。当虚引用所引用的对象被GC回收时,JVM会把该虚引用加入到关联的引用队列中,通知应用程序虚引用所引用的对象已经被回收。下面是虚引用的使用攻略:

  1. 虚引用的创建

虚引用可以通过java.lang.ref.PhantomReference类的构造函数创建。代码示例:

Object object = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(object, referenceQueue);

上述代码中,我们创建了一个对象object,一个引用队列referenceQueue,以及一个虚引用phantomReference。虚引用phantomReference指向对象object,并且当对象被GC回收时,会被加入到引用队列referenceQueue中。

  1. 虚引用的使用

虚引用的主要作用是在对象被GC回收时,通知应用程序。例如,我们可以使用虚引用来监控对象是否被GC回收,以此判断对象是否已经被销毁,避免内存泄漏等问题。代码示例:

try {
    Object object = new Object();
    ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
    PhantomReference<Object> phantomReference = new PhantomReference<>(object, referenceQueue);
    object = null; //手动将object设置为null,使其可以在经过垃圾回收后被释放
    System.gc(); //手动触发垃圾回收
    Thread.sleep(1000); //等待一段时间,让垃圾回收完成
    if(phantomReference.isEnqueued()) { //如果phantomReference已经被加入引用队列,则表示对象已经被GC回收
        System.out.println("对象已经被销毁");
    } else {
        System.out.println("对象没有被销毁");
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}

上述代码中,我们手动将对象object设置为null,使其可以在经过垃圾回收后被释放。然后手动触发垃圾回收,并等待一段时间,让垃圾回收完成。最后,在判断虚引用是否被加入到引用队列中,从而判断对象是否已经被销毁。

除了上述示例外,虚引用还有其他的用途,例如用来跟踪对象的创建和销毁、在对象被销毁之前执行一些必要的清理操作等。