All object instances in Java are allocated on the heap and can only be accessed through object references. When we are creating object we are storing references for accessing objects in future
Object o = new Object();
Here “o” is strong reference, beside this type of reference Java also has other types of references which are implemented in java.lang.ref package, from Java 1.2 In this package we have three reference-object classes: Weak Reference, Phantom Reference and Soft Reference.
Weak References:
Weak reference is a reference which doesn't have enough force to prevent Garbage Collector(GC) deleting object. This type of references are useful when we are implementing caching functionality. Suppose we have cache of images and different threads of system are using it, when system no more needs some images, GC will not be able to delete object because cache has strong reference to it and object will stay in memory forever. To prevent such situations we can refer objects in cache with weak references and GC will delete it as soon as it detects its weakly reachability.
You can create weak reference like this:
WeakReference
weakImage = new WeakReference
(image);
And for accessing Image object you can use weakImage.get() which returns actual object, But It also can return null which means that there are no strong references to this object.
Another Way for creating WeakReference is:
ReferenceQueue q = new ReferenceQueue();
WeakReference
weakImage = new WeakReference
(image, q);
ReferenceQueue class gives us flexibility for tracking references, When WeakReference starts returning null it means that object is garbage and reference will be added to the queue, which you can use for further cleanup.
Soft Reference:
Soft Reference behaves like weak references, except when GC determines object is softly reachable, then it may clear this object or not. But we can be guaranteed that this object will be cleared before virtual machine throws OutOfMemoryError . This mean that softly reachable objects will stay in memory until memory occupied be them is not critical and we have enough memory for creating other objects.
Phantom Reference:
Phantom references are different from soft and weak references, it's get() method always returns null. The only use of this reference is to track when object is enqueued. But why we need it if we already have other references?
Let's introduce such class:
public class SoftRef {
static SoftRef ref = null;
String t;
public SoftRef(String t) {
this.t = t;
}
static public void main(String[] args) {
SoftRef obj = new SoftRef("test Obj");
obj = null;
System.gc();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
ref = this;
System.out.println("deleted");
}
}
This class has weird finalize method, it is resurrecting itself – creating strong reference to itself therefore GC will not delete it. Java Language Specification clams that finalize() method will be invoked maximum once, so it guarantee that object can't resurrect always.
In this case WeakReferences will be enqueued before object is really deleted and reference will become dead beside object stay alive. Here PhantomReferences can help, Phantom references are enqueued when objects are deleted from memory and get() method always returns null to prevent resurrecting object. So phantom references are good for determining exactly when object is deleted from memory.

4 comments:
Cool :) You were right. I had never heard about Phantom references :))
Thanks for sharing
Check out Bob Lee's great talk on the Java reference API for a lot more of the obscure details of these (slide link at bottom):
http://thestrangeloop.com/sessions/ghost-virtual-machine-reference-references
I'm not really sure with that 'this.ref = this' assignment. It is really matter of actual GC implementation, so you can't really tell when is "unused" object really deleted, but as far as I know, clever GCs detect circular references and deal with them properly.
@Mamuf
yes GCs detect circular references. But this case won't be detected as circular reference, because "ref" is static and it's not instance variable.
Post a Comment