当前位置:首页 > JAVA > 正文内容

java学习引用类型之虚引用

高老师1年前 (2023-07-14)JAVA617

虚引用(Phantom Reference)是Java中最弱的一种引用类型,它在Java.lang.ref包中定义。与弱引用和软引用不同,虚引用主要用于跟踪对象被垃圾回收器回收的活动,并不能通过虚引用获取到对象的实例。

虚引用的特点如下:

  1. 获取对象:无法通过虚引用直接获取到被引用的对象实例。通过虚引用调用get()方法始终返回null
  2. 生命周期控制:虚引用主要用于在对象被垃圾回收时接收一个系统通知。在创建虚引用时,需要将其与一个引用队列(ReferenceQueue)关联。当对象被垃圾回收器回收时,会将该虚引用添加到关联的引用队列中,通过监视该引用队列可以得知对象已经被回收。
  3. 对象回收前的清理操作:在虚引用被添加到引用队列之前,可以通过重写Reference类的finalize()方法,在对象即将被回收之前执行一些清理操作。

虚引用的主要应用场景是与引用队列配合使用。通过虚引用,我们可以追踪对象的销毁过程,并在对象即将被回收时进行一些必要的清理工作,比如释放资源、记录日志等。典型的应用场景包括内存管理和对象销毁监控。

需要注意的是,虚引用不能用于阻止对象被垃圾回收。它仅仅提供了对象回收的通知,并且在回收之前执行一些清理操作。

当使用虚引用的时候,需要将其与一个引用队列(ReferenceQueue)关联。下面是一个简单的示例代码,演示了如何使用虚引用和引用队列来追踪对象的销毁过程:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class PhantomReferenceExample {
    public static void main(String[] args) {
        // 创建一个引用队列
        ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue<>();

        // 创建一个MyObject对象,并关联一个虚引用和引用队列
        MyObject myObject = new MyObject();
        PhantomReference<MyObject> phantomReference = new PhantomReference<>(myObject, referenceQueue);

        // 将MyObject对象置为null,使其没有强引用指向它
        myObject = null;

        // 在内存不足时尝试进行垃圾回收
        System.gc();

        // 检查引用队列,判断对象是否已经被回收
        while (true) {
            PhantomReference<? extends MyObject> reference = (PhantomReference<? extends MyObject>) referenceQueue.poll();
            if (reference != null) {
                System.out.println("MyObject对象已被垃圾回收");
                break;
            }
        }
    }
}

class MyObject {
    // 可以在这里添加一些清理操作或其他逻辑
}

在上述示例中,我们创建了一个MyObject对象,并关联了一个虚引用和引用队列。随后,将MyObject对象置为null,使其没有强引用指向它。然后,调用System.gc()尝试进行垃圾回收。

在循环中,我们通过referenceQueue.poll()方法从引用队列中获取虚引用。如果虚引用不为null,就表示MyObject对象已经被垃圾回收。这时可以执行一些清理操作或其他逻辑。当然,在实际使用中,我们可能会将虚引用与多个对象关联,以便跟踪多个对象的销毁过程。

需要注意的是,由于垃圾回收器的行为是不确定的,无法保证在调用System.gc()后立即得到虚引用通知。因此,可能需要对示例代码进行一定的调整和优化,以满足具体需求。

虚引用的主要应用场景是与引用队列(ReferenceQueue)配合使用,用于跟踪对象的销毁过程并执行一些必要的清理操作。以下是虚引用的几个典型应用场景:

  1. 内存管理:通过虚引用可以追踪对象的销毁过程,从而在对象被回收之前执行一些资源释放的操作,比如关闭文件、释放网络连接、释放内存等。这样可以优化资源的利用和释放,提高程序的性能和稳定性。
  2. 对象销毁监控:有时候需要监控某个对象的销毁状态,比如在持久化框架中追踪对象的生命周期,记录日志或更新数据库等。通过将对象与虚引用关联,并设置引用队列,可以在对象被回收时得到通知,进而采取相应的措施。
  3. 防止对象复活:在某些场景下,我们可能希望确保一个对象被垃圾回收后不会再次被使用。通过将对象与虚引用关联,可以在回收对象后的处理逻辑中进行判断,如果发现对象已经被回收,则阻止它继续被使用。

需要注意的是,虚引用不能用于阻止对象被垃圾回收,而是用于跟踪对象的销毁过程。当垃圾回收器准备回收一个对象时,如果发现它的虚引用已经添加到引用队列中,那么会将虚引用放入引用队列,并通过监视该引用队列判断对象是否已被回收。

总之,虚引用的主要作用是允许我们在对象被垃圾回收前进行一些必要的操作,并且与引用队列的配合使用可以跟踪对象的销毁过程。这为我们提供了一些灵活性和控制能力,使得对象的销毁与资源释放更加可控和安全。

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/460.html

分享给朋友:

“java学习引用类型之虚引用” 的相关文章

java编译编码问题,java编译执行时编码问题

java编译编码问题,java编译执行时编码问题

public class test {     public static void main(String[] args) {     &...

java一个类可以有多个构造方法

java一个类可以有多个构造方法

java一个类可以有多个构造方法,根据传参类型和个数来匹配执行哪个构造方法。public class Member {     public Member(){      ...

java限制1个方法同一时间只能被一个线程访问

java限制1个方法同一时间只能被一个线程访问

java限制1个方法同一时间只能被一个线程访问public synchronized void setOrderPay(){ }加上synchronized 修饰符即可...

java final 修饰符,java通过final修饰符创建常量,,java通过final修饰符声明方法不可被修改

java final 修饰符,java通过final修饰符创建常量,,java通过final修饰符声明方法不可被修改

(1).final 修饰符通常和 static 修饰符一起使用来创建类常量。(2).父类中的 final 方法可以被子类继承,但是不能被子类重写,声明 final 方法的主要目的是防止该方法的内容被修改。public class Member {   ...

java Character 类,java判断字符是否是一个字母,java判断字符是否是一个数字,java判断字符是否是一个空白,java判断字符是否是小写字母,java判断字符是否是大写字母,java转换字符为大写,java转换字符为小写

java Character 类,java判断字符是否是一个字母,java判断字符是否是一个数字,java判断字符是否是一个空白,java判断字符是否是小写字母,java判断字符是否是大写字母,java转换字符为大写,java转换字符为小写

java判断字符是否是一个字母System.out.println(Character.isLetter('a'));java判断字符是否是一个数字System.out.println(Character.isDigit('0'));java判断字符是否是一个空白Sy...

java数组,java创建数组,java创建数组并赋值,java数组元素个数,java foreach 循环数组,java数组排序

java数组,java创建数组,java创建数组并赋值,java数组元素个数,java foreach 循环数组,java数组排序

(1).创建数组double[] myList = new double[size];  //推荐创建方式 double myList[] = new double[size];  ...