Đây là mã của tôiTại sao tôi không nhận được PhantomReference từ ReferenceQueue cho một đối tượng hoàn chỉnh?
public class FinalizableObject {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize() invoked for " + this);
super.finalize();
}
}
public class Main {
private static void test() throws InterruptedException {
ReferenceQueue<FinalizableObject> rq = new ReferenceQueue<FinalizableObject>();
FinalizableObject obj = new FinalizableObject();
PhantomReference<FinalizableObject> pr1 = new PhantomReference<FinalizableObject>(obj, rq);
obj = null;
System.gc();
Reference<? extends Object> ref = rq.remove();
System.out.print("remove " + ref + " from reference queue\n");
}
public static void main(String[] args) {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Nó rất lạ, rq.remove() sẽ bị chặn vĩnh viễn. Tại sao tham chiếu ma trận của đối tượng cuối cùng của tôi không thể được đưa vào hàng đợi tham chiếu? Nó đã được GC thu thập?
Cảm ơn bạn rất nhiều.
Tôi biết FinalizerReferenceQueue và FinalizerDeamon, 2 lần GC có thể thu thập hoàn toàn một đối tượng cuối cùng. Nhưng tôi không thể hiểu tại sao 100 lần GC sẽ kích hoạt nó được thu thập (thậm chí 20 lần GC không thể kích hoạt enqueue).
Mặt khác, nếu tôi thay thế PhantomReference bằng WeakReference, nó có thể loại bỏ tham chiếu rất nhanh.
–
@DevboardFan Điều này là bởi vì để gọi phương thức 'finalize()' không tầm thường, JVM xây dựng đặc biệt Finalizer-Thread, cũng phải được thu thập và hoàn thành. – Andremoniy
Cảm ơn bạn rất nhiều! –