虚引用的一些主要使用场景和特点:
- 跟踪对象被垃圾回收的状态
- 管理堆外内存
- 调试和分析
跟踪对象被垃圾回收的状态
虚引用的主要用途是跟踪对象何时被垃圾回收。当一个对象仅被虚引用引用时,在下一次垃圾回收时,这个对象会被回收,而虚引用会被加入到其关联的引用队列中。
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> reference = new PhantomReference<>(new Object(), queue);// 等待对象被回收
Reference<?> polledRef = queue.poll();
if (polledRef != null) {System.out.println("Object has been collected.");
}
管理堆外内存
虚引用常用于管理堆外内存(Direct Memory)。例如,在NIO中的DirectByteBuffer使用虚引用来管理堆外内存的释放。
public class DirectMemoryManager {private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<>();static class DirectMemoryReference extends PhantomReference<Object> {private final long address;DirectMemoryReference(Object referent, long address) {super(referent, QUEUE);this.address = address;}void cleanUp() {// 释放堆外内存unsafe.freeMemory(address);}}public static void allocateMemory(Object owner, long size) {long address = unsafe.allocateMemory(size);new DirectMemoryReference(owner, address);}public static void processQueue() {DirectMemoryReference ref;while ((ref = (DirectMemoryReference)QUEUE.poll()) != null) {ref.cleanUp();ref.clear();}}
}
调试和分析
虚引用可以用于调试内存泄漏或分析对象生命周期,因为它们允许你在不影响对象正常垃圾回收的情况下跟踪对象。