Java Reference
In-Depth Information
Using the PhantomReference Class
Phantom references work a little differently than soft and weak references. A PhantomReference object must be
created with a ReferenceQueue . When the garbage collector determines that there are only phantom references to
an object, it finalizes the object and adds the phantom references to their reference queues. Unlike soft and weak
references, it does not clear the phantom references to the object automatically. Programs must clear the phantom
reference to the object by calling the clear() method. A garbage collector will not reclaim the object until the
program clears the phantom references to that object. Therefore, a phantom reference acts as a strong reference
as long as reclaiming of objects is concerned. Why would you use a phantom reference instead of using a strong
reference? A phantom reference is used to do post-finalization and pre-mortem processing. At the end of post-
finalization processing, you must call the clear() method on the PhantomReference object, so its referent will be
reclaimed by the garbage collector. Unlike the get() method of the soft and weak references, the phantom reference's
get() method always returns null . An object is phantom reachable when it has been finalized. If a phantom reference
returns the referent's reference from its get() method, it would resurrect the referent. This is why phantom reference's
get() method always returns null .
Listing 11-10 demonstrates the use of a phantom reference to do some post-finalization processing for an object.
Note that the post-finalization processing cannot involve the object itself because you cannot get to the object using
the get() method of the phantom reference. You may get a different output when you run this program.
Listing 11-10. Using PhantomReference Objects
// PhantomRef.java
package com.jdojo.gc;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomRef {
public static void main(String[] args){
BigObject bigObject = new BigObject(1857);
ReferenceQueue<BigObject> q = new ReferenceQueue<BigObject> ();
PhantomReference<BigObject> pr = new PhantomReference<BigObject>(bigObject, q);
/* You can use BigObject reference here */
// Set BigObject to null, so garbage collector will find only the
// phantom reference to it and finalize it.
bigObject = null;
// Invoke garbage collector
printMessage(pr, "Invoking gc() first time:") ;
System.gc();
printMessage(pr, "After invoking gc() first time:");
// Invoke garbage collector again
printMessage(pr, "Invoking gc() second time:") ;
System.gc();
printMessage(pr, "After invoking gc() second time:");
}
 
Search WWH ::




Custom Search