Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Phantom reference vs weak reference with respect to Reference queue

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?

like image 270
Anand Avatar asked Oct 06 '14 07:10

Anand


People also ask

What are strong references and weak references in GC?

The garbage collector cannot collect an object in use by an application while the application's code can reach that object. The application is said to have a strong reference to the object. A weak reference permits the garbage collector to collect the object while still allowing the application to access the object.

What is the purpose of a weak reference?

A weak reference allows the garbage collector to collect an object while still allowing an application to access the object. If you need the object, you can still obtain a strong reference to it and prevent it from being collected.

What is weak reference and soft reference in Java?

WeakReference: is used to hold an object which will become eligible for the garbage collection as soon as it is not reachable by the program. SoftReference: lives longer, it will only be garbage collected before an OutOfMemoryError is thrown.

What is the use of phantom reference in Java?

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used to schedule post-mortem cleanup actions.


1 Answers

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.)

like image 84
Xiao-Feng Li Avatar answered Oct 30 '22 16:10

Xiao-Feng Li