Understanding of references in java cannot really be accomplished without the understanding of Garbage Collector in java.
All the references created in java are by default Strong references. Lets try to understand with the help of an example what is so strong about a strong reference.
Strong reference :
MyClass myObj = new MyClass();
What above piece of code essentially does is creates a new object, allocates it on the heap. The strong reference myObj points to the object on the heap. The reference is strong in a sense that garbage collector can't reclaim the memory unless the reference is made null.
Weak Reference :
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTCRWBbb10mMtippZnoQsK2z-2d5Q1_wOb0wQTNOVYkm-szrXhSuUmuPGY8xrkyTQdZ-fo3tM1MJVl56NwysxtK2ltt_r2nN4mAEbFzGn8qWxRYO-xwBDi71XxXA4JJBnPzreGbaJQojpO/s1600/weakRef.png)
WeakReference is an indirect way of referencing an object on heap.
When the referent referred by weakReference becomes null, the get() call on weakReference returns null.
A weakRef reference wraps the employee object and if the employee is made null, the get() call on weakRef returns null and the employee object can be garbage collected.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoxJqzScOLTR55-9WKSGXb2Cpz9lDbjKIAfTlZaZ5ptTdIdSihkNlrLwgkqoAtZ5nGNGbR7Sou_PFF26vdQF6gv1NlhDqyV4gvJ_-Y65kRQ-OIfhu2Dl2K3DejwrPHGY5jiO1ICAGW-Upz/s1600/strongHashMap.png)
We are creating instances of a class Employee and putting it in a HashMap.
Even though reference 'e' becomes null outside the for loop but the Employee objects are still reachable through employeeMap and will not be garbage collected. It can be verified that the size of map is 10,000 and contains the Employee objects.
package heap;
import java.util.HashMap;
import java.util.Map;
public class OrdinaryHM{
public static Map <Employee, Integer> employeeMap = new HashMap<Employee, Integer>();
public static void main(String[] args) throws Exception{
// Create multiple employee objects and store it in map
Employee e = null;
for (int i = 0; i < 10000; i++) {
// Notice that e has a scope inside for loop only,
// and will be null outside the loop
e = new Employee();
employeeMap.put(e, i);
}
/* Stop the application for 5 seconds to allow
* garbage collector to do its work
*/
Thread.sleep(5000);
/* The size of Map is 10000 which means none of the employee object is garbage
* collected. Because they are still reachable through map 'employeeMap'
*/
System.out.printf("Employee map size : %d ",employeeMap.size());
}
}
Output : Employee map size : 10000
There might be scenarios where we might want to evict the entries from the map, when the actual references have become null.
Consider an example where many Observers have subscribed to a Observable. The Observable must maintain the references of all Observers in a collection. If some of the observers are made null, they will still be maintained in the collection because they are still reachable through the collection reference. Although there is no need to retain them in the collection. This is a memory leakage scenario which should be avoided.
This can be avoided using the WeakHashMap which is based upon WeakReference.
WeakHashMap solves the problem suggested above by making use of WeakReference internally.
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>
As we can see in above snippet that the Entry class in WeakHashMap extends WeakReference. And also the key in the WeakHashMap is also a WeakReference. This means that the entries and key in the WeakHashMap are indirectly referred through referrent.
Let consider below example using WeakHashMap to store data.
package heap; import java.util.Map; import java.util.WeakHashMap; public class WeakHMUsuage{ public static Map<Employee, Integer> employeeMap = new WeakHashMap<Employee, Integer>(); public static void main(String[] args) throws Exception{ // Create multiple employee objects and store it in map Employee e = null; for (int i = 0; i < 10000; i++) { // Notice that e has a scope inside for loop only, // and will be null outside the loop e = new Employee(); employeeMap.put(e, i); } /* Stop the application for 5 seconds to allow * garbage collector to do its work */ Thread.sleep(5000); /* The size of Map is 5805 which means garbage collection is taking place.
* As the elements are reachable through weak reference. */ System.out.printf("Employee map size : %d ",employeeMap.size()); } } Output : Employee map size : 5805
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHoqsonXsSI5lpjzc2uZiby0AD9Qcfg_w4Kz1wGhADvAfs-ynhYfBUoNh8tS8xNWDmIrchHUGD2jzwjsfIK4e9VZ7YJ8veu8nDSgBoKupF0csvc1pzCagETHkUZExP-QyejmhsZGizIrQA/s1600/WeakHashMap.png)
The size of map is not reduced to zero because GC works on its own terms and conditions and when it feels suitable.
No comments:
Post a Comment