javagarbage-collectionphantom-reference

Importance of phantomreference in java


I wanted to understand the below statement in bold. What does it means? (Link)

An object which overrides finalize() must now be determined to be garbage in at least two separate garbage collection cycles in order to be collected. When the first cycle determines that it is garbage, it becomes eligible for finalization. Because of the (slim, but unfortunately real) possibility that the object was "resurrected" during finalization, the garbage collector has to run again before the object can actually be removed. And because finalization might not have happened in a timely fashion, an arbitrary number of garbage collection cycles might have happened while the object was waiting for finalization. This can mean serious delays in actually cleaning up garbage objects, and is why you can get OutOfMemoryErrors even when most of the heap is garbage.

What phantomreference solves

With PhantomReference, this situation is impossible -- when a PhantomReference is enqueued, there is absolutely no way to get a pointer to the now-dead object (which is good, because it isn't in memory any longer). Because PhantomReference cannot be used to resurrect an object, the object can be instantly cleaned up during the first garbage collection cycle in which it is found to be phantomly reachable.

Please help me understand the problem & the solution

Thanks


Solution

  • Contrary to popular belief, finalize methods are not triggered when their associated objects are garbage-collected, but rather when their associated objects would have been garbage-collected but for the existence of their non-default finalize methods. Objects cannot actually be garbage-collected until the system can be 100% certain that no reference to them will ever exist, but the act of running a finalize method creates a strong rooted reference to the object in question which will exist at least until the method exits. If during the execution of finalize a reference to the object gets stored elsewhere, that reference could continue to exist indefinitely. Consequently, no object whose finalized method is going to be called, nor any other object to which such an object holds a direct or indirect strong reference, can be collected until after the finalize method has run and the next GC cycle confirms that no reference to the object exists anymore.

    The PhantomReference class serves to encapsulate a different paradigm: rather than keeping an object alive so the system can notify it that it's been abandoned and the only reason it's still alive is so it can receive notification of abandonment, objects requiring cleanup should create helper objects to process notification of their abandonment. If the helper objects avoid keeping references to any outside objects they don't "own", their existence won't interfere with the collection of their parent object, or other objects to which the parents hold direct or indirect references. The helper objects generally won't hold enough information to let them "do much", but that's good because they shouldn't have to do much. Instead, their design should be focused on performing the cleanup that will be required if their parent is abandoned.