虚引用(Phantom Reference)是Java中最弱的一种引用类型,它在Java.lang.ref包中定义。与弱引用和软引用不同,虚引用主要用于跟踪对象被垃圾回收器回收的活动,并不能通过虚引用获取到对象的实例。
虚引用的特点如下:
get()
方法始终返回null
。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)配合使用,用于跟踪对象的销毁过程并执行一些必要的清理操作。以下是虚引用的几个典型应用场景:
需要注意的是,虚引用不能用于阻止对象被垃圾回收,而是用于跟踪对象的销毁过程。当垃圾回收器准备回收一个对象时,如果发现它的虚引用已经添加到引用队列中,那么会将虚引用放入引用队列,并通过监视该引用队列判断对象是否已被回收。
总之,虚引用的主要作用是允许我们在对象被垃圾回收前进行一些必要的操作,并且与引用队列的配合使用可以跟踪对象的销毁过程。这为我们提供了一些灵活性和控制能力,使得对象的销毁与资源释放更加可控和安全。
public class test { public static void main(String[] args) { &...
java一个类可以有多个构造方法,根据传参类型和个数来匹配执行哪个构造方法。public class Member { public Member(){  ...
java限制1个方法同一时间只能被一个线程访问public synchronized void setOrderPay(){ }加上synchronized 修饰符即可...
(1).final 修饰符通常和 static 修饰符一起使用来创建类常量。(2).父类中的 final 方法可以被子类继承,但是不能被子类重写,声明 final 方法的主要目的是防止该方法的内容被修改。public class Member {  ...
java判断字符是否是一个字母System.out.println(Character.isLetter('a'));java判断字符是否是一个数字System.out.println(Character.isDigit('0'));java判断字符是否是一个空白Sy...
(1).创建数组double[] myList = new double[size]; //推荐创建方式 double myList[] = new double[size];  ...