虛引用的一些主要使用場景和特點:
- 跟蹤物件被垃圾回收的狀態
- 管理堆外記憶體
- 除錯和分析
跟蹤物件被垃圾回收的狀態
虛引用的主要用途是跟蹤物件何時被垃圾回收。當一個物件僅被虛引用引用時,在下一次垃圾回收時,這個物件會被回收,而虛引用會被加入到其關聯的引用佇列中。
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();
}
}
}
除錯和分析
虛引用可以用於除錯記憶體洩漏或分析物件生命週期,因為它們允許你在不影響物件正常垃圾回收的情況下跟蹤物件。