Types of Reference in Java - Strong, Weak, Soft, Phantom References - Java @ Desk

Monday, January 26, 2015

Types of Reference in Java - Strong, Weak, Soft, Phantom References

Types of Reference in Java - Strong Reference, Weak Reference, Soft Reference, Phantom Reference

Before diving into references, it’s important to know that Java has its own memory management system. The garbage collector in Java reclaims the memory whenever the application runs low on memory. The garbage collector can free the memory only from those objects which are eligible for garbage collection. This eligibility for garbage collection depends on the type of reference the object has. The command System.gc() can be used to request for garbage collection.

There are 4 types of references in Java:

1. Strong Reference
This is the normally used type of reference. Whenever we create a new object, we create a strong reference to that object. All objects which have strong references will never be garbage collected. By using strong references, we send a message to the garbage collector that the object is actively used it should not be garbage collected.
In the example below, the object strong1 is set to null and the GC is requested. However, since the object strong2 refers to strong1 and strong2 has a strong reference, therefore strong2 is not garbage collected.

Sample code:
private void strongReferenceTry() {
 Bar strong1 = new Bar();
 Bar strong2 = strong1; 

 System.out.println("Get the strong reference : "+ strong2);

 strong1 = null; // Removing strong reference
 System.gc(); // Requesting garbage collection

 System.out.println("After Removing strong reference and requesting Garbage Collection");
 System.out.println("Get the strong reference : "+ strong2);
}

Output:
Get the strong reference : Bar@7150bd4d
After Removing strong reference and requesting Garbage Collection
Get the strong reference : Bar@7150bd4d



2. Weak Reference
The objects which have weak references will be garbage collected in the next cycle of garbage collection. For example, Weak Hash Map in Java by default uses weak reference.
In the example below, you can see that once the strong reference to the object is removed, then the weak reference is also removed from the memory in the next GC cycle.

Sample code:
private void weakReferenceSample (){  

 Bar strong = new Bar(); // creating strong Reference
 WeakReference<Bar> weakReference = new WeakReference<Bar>(strong); //weak reference

 System.out.println("Get the weak reference : "+ weakReference.get());

 strong = null; // Removing strong reference
 System.gc(); // Requesting garbage collection

 System.out.println("After Removing strong reference and requesting Garbage Collection");
 System.out.println("Get the weak reference : "+ weakReference.get());
}

Output:
Get the weak reference : Bar@6bbc4459
After Removing strong reference and requesting Garbage Collection
Get the weak reference : null



3. Soft Reference
This type of reference also allows the garbage collection of objects. Soft reference is just like weak reference, with the difference that the objects having soft reference will not be garbage collected until and unless there is a memory crunch. This is unlike the case of weak references which will be garbage collected mostly in the next garbage collection cycle.
In the example below, even though there is no strong reference to the object, it still remains in the soft reference as the garbage collector does not remove it from the memory.



Sample code:
private void SoftReferenceSample (){
 
 Bar strong = new Bar(); // creating strong Reference
 SoftReference<Bar> softReference = new SoftReference<Bar>(strong); //soft reference

 System.out.println("Get the soft reference : "+ softReference.get());

 strong = null; // Removing strong reference
 System.gc(); // Requesting garbage collection

 System.out.println("After Removing strong reference and requesting Garbage Collection");
 System.out.println("Get the soft reference : "+ softReference.get()); 
}

Output:
Get the soft reference : Bar@6bbc4459
After Removing strong reference and requesting Garbage Collection
Get the soft reference : Bar@6bbc4459



4. Phantom Reference
This is a completely different concept. Calling get() on a phantom reference will always return null. When you construct a phantom reference, you must always pass it in a ReferenceQueue. Once the phantom reference is garbage collected, the object will be added into this ReferenceQueue, and thus, indicates when your object is garbage collected.
Phantom references have little use apart from helping us find when an object is garbage collected.

Sample code:
private void phantomReferenceSample (){

 ReferenceQueue<Bar> queue = new ReferenceQueue<Bar>();
 Bar strong = new Bar(); // creating strong Reference
 PhantomReference<Bar> phantomBar = 
 new PhantomReference<WeakReferance.Bar>(strong, queue); // creating phantom reference

 System.out.println("Get the phantom reference : "+ phantomBar.get());
 System.out.println("Phantom reference queue :  " + phantomBar.isEnqueued() );

 strong = null; // Removing strong reference
 System.gc(); // Requesting garbage collection

 System.out.println("After Removing strong reference and requesting Garbage Collection");
 System.out.println("Get the phantom reference : "+ phantomBar.get());
 System.out.println("Phantom reference queue :  " + phantomBar.isEnqueued() );
}

Output:
Get the phantom reference : null
Phantom reference queue :  false
After Removing strong reference and requesting Garbage Collection
Get the phantom reference : null
Phantom reference queue :  true

This post is written by Jerin Joseph. He is a freelance writer, loves to explore latest features in Java technology.







2 comments: