Search code examples
javaphantom-reference

What is the relationship between the PhantomReference and ReferenceQueue?


I am having a little confusion about the PhantomReference in java. When I looked in online articles most of them mentioned that the PhantomReference object will return null after creation even if we invoke get() on the reference and also it mentioned the objects are phantomly reachable will be inserted into the ReferenceQueue when the PhantomReference is removed from the memory.

I have tried the following code example but I have a confusion about the result.

Equipment equipment = new Equipment();  
ReferenceQueue queue = new ReferenceQueue();  
PhantomReference pr = new PhantomReference(equipment, queue);

System.out.println(pr.get());  
System.out.println(queue.poll()); 

Above two statements prints null. If the pr.get() returns null does it mean the object referred by pr is garbage collected? If it is so, why the object is still haven't added to the priority queue?

Can anybody help please me to clarify this. I apologies from you if my understanding is wrong regarding the PhantomReference and the ReferenceQueue.

Please describe these two terms simply as well

thanks a lot


Solution

  • PhantomReference#get() always returns null.

    Returns this reference object's referent. Because the referent of a phantom reference is always inaccessible, this method always returns null.

    You can't know whether it was collected or not through get().

    If it is so, why the object is still haven't added to the priority queue

    The javadoc states

    If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.

    So either the instance hasn't been garbage collected by the time poll() (non-blocking) was called or the instance was garbage collected, but the corresponding PhantomReference wasn't added to the ReferenceQueue.

    You can help it along by setting the strong reference to null and requesting a GC, but also blocking to remove the Reference from the queue.

    equipment = null;
    System.out.println(pr.get());
    System.gc();
    System.out.println(queue.remove()); // block and wait for it to be added