1

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

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Dilan
  • 1,389
  • 5
  • 14
  • 24

1 Answers1

2

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
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thanks for your answer and it helped me to understand the context clearer but I would like to know why you call System.gc(); and then call queue.remove(). Can you please explain it – Dilan Oct 08 '14 at 16:37
  • @user3115189 `System.gc()` is a _suggestion_ to the Garbage Collector to garbage collect anything it can. It gives us better chances of seeing the `Equipment` object being garbage collected. `queue.remove()` is called instead of `poll()` because it blocks waiting for an entry to be available in the queue. See the quote from the javadoc in my answer. The phantom reference can be added to the queue at some **later time**. We want to wait until that happens. – Sotirios Delimanolis Oct 08 '14 at 17:12