Understanding Phantom reference vs weak reference with respect to Reference queue
Asked Answered
T

1

7

As per the link https://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html, PhantomReferences are enqueued only when the object is physically removed from memory and WeakReferences are enqueued before finalization or garbage collection has actually happened.

The difference is in exactly when the enqueuing happens. WeakReferences are enqueued as soon as the object to which they point becomes weakly reachable. This is before finalization or garbage collection has actually happened; in theory the object could even be "resurrected" by an unorthodox finalize() method, but the WeakReference would remain dead. PhantomReferences are enqueued only when the object is physically removed from memory, and the get() method always returns null specifically to prevent you from being able to "resurrect" an almost-dead object.

whereas as per http://www.ibm.com/developerworks/library/j-refs/, PhantomReference is added to its ReferenceQueue before the heap object is freed and and WeakReferences are added to its ReferenceQueue after finalization or garbage collection.

Unlike soft and weak references, the PhantomReference is added to its ReferenceQueue before the heap object is freed. (Remember, all PhantomReference objects must be created with an associated ReferenceQueue.) This allows for action to be taken before the heap object is reclaimed.

When the heap object's finalize() method is run and its memory freed, the WeakReference object is added to its ReferenceQueue, if it exists.

I am confused. Which one is correct?

Basically i want to know the difference between weak and phantom reference with respect to Reference Queue?

Tithe answered 6/10, 2014 at 7:31 Comment(0)
C
9

On ReferenceQueue:

Both WeakReference and PhantomReference will be enqueued after their referent (referenced object) not strongly-reachable, if they have a non-null reference-queue registered when they were created.

Before it is passed for enqueuing, WeakReference clears (nullifies) the referent field to make the referent completely unreachable. When the WeakReference is cleared, application can no longer get() the referent. That means, when later the WeakReference is enqueued, get() returns null. WeakReference may not have a reference-queue registered when it was created. Application can detect if its referent is unreachable by get()-ing it. Sometimes reference-queue is handy to manage the WeakReferences when the application does not want to manage them explicitly.

Before it is passed for enqueuing, PhantomReference does not clears the referent field. When it enqueued, the referent is still referenced by the PhantomReference. The referent is only cleared by the application explicitly after it dequeues the reference-queue. If application does not clear it, the referent remains there till both it and its PhantomReference become reclaimed together. In any case, get() on PhantomReference always return null, even when it is not cleared. So application cannot detect if its referent is unreachable by get()-ing it. Application can only detect that by checking if the PhantomReference is queued. For this reason, a PhantomReference must be created with a reference-queue registered; Otherwise, it is useless.

On finalization:

When WeakReference is cleared, the referent becomes unreachable. If the referent has a non-default finalizer, it is subjected to finalization, hence to be resurrected. If the referent does not have non-default finalizer, it is subject to be reclaimed by GC. In other words, WeakReferences are processed before finalization.

If the referent of a PhantomReference is reachable only through the PhantomReference, it is not yet phantomly-reachable. It is only phantomly-reachable if it remains so (only reachable through the PhantomReference) after finalization. In other words, PhantomReferences are processed after finalization. Only those referents that are not resurrected by finalization are phantomly-reachable, thus they are sure to die. But since then PhantomReference will be enqueued, those referents are not dead yet. They only become reclaimable when the PhantomReferences are cleared later by the application, or the PhantomReferences become unreachable themselves (then the PhantomReference and its referent become reclaimed together.)

Chimborazo answered 16/10, 2015 at 3:13 Comment(3)
I assume the sentences you write are each corrrect, but I am still completely confused why I would ever need PhantomReference. (I constantly use WeakReference and understand exactly what it does.)Extensive
@StefanReich PhantomReference has a very special property that the application knows exactly the referent is dead and surely be reclaimed by GC, i.e., never get resurrected, because it has been finalized before enqueued. This property is important in some use cases. For example you want to new an object1 only after you know exactly an old object2 is surely reclaimable.Chimborazo
OK I get that point. If this is about not physically running out of memory, you want the PhantomReference guarantee that an object was freed. ThanksExtensive

© 2022 - 2024 — McMap. All rights reserved.