Weak References in java

Normally the Java garbage collector plays safe. It will only free up the memory used by an object when that object can no longer be accessed by the program. Once an object become impossible to reach it is eligible for collection, and eventually its memory will be reclaimed.

This eliminates one of the most common programming errors in some other languages (like C++), where code accidentally tries to access an object that has been freed. Unfortunately it can lead to another problem, where you leave open a potential access route to an object that you don’t need any more. Memory fills up, and the program slows down or reports an “Out of Memory” error.

To avoid this, you can be very careful to close off access paths to an object once you have finished using it. Java 2 introduces another alternative, the weak reference. Weak references provide access to an object without preventing it from being freed. When you use a weak reference you have to accept that the object referred to may have disappeared, which results in the reference being automatically set to null. On the other hand, the weak reference will not hold the object in memory once it is inaccessible via normal references (or via “soft” references – see below). Weak references are not appropriate in all circumstances, but sometimes they can make code easier to write and understand.

The most common use of weak references is indirect – they are used internally by the WeakHashMap class. Like HashMap, WeakHashMap associates key objects with values. However, once the key object becomes inaccessible via stronger references it becomes eligible for garbage collection. When it is freed, the map entry magically disappears. The assumption here is that if you are not using the key anywhere other than in the map you will have no need to look it up, so it should be freed.

Other specialist references are soft references (which inhibit collection until memory runs short), and phantom references (used for cleanup when objects are freed).

For more detailed (and precise) information, see the java.lang.ref API docs, and also the articleReference Objects and Garbage Collection at the Sun website.

The good thing about weak reference is that in my opinion it is one of the best ways to implement an in-memory cache which we usually implement ourselves when we need to keep data that do not consistently change but frequently accessed in memory and when the cost of going for a fully-fledged caching implementation like the JBoss cache or EHCache is too much. Quite often I have implemented caching solutions and have also seen production code similar to the following code snippet;

import java.util.HashMap;  
import java.util.Map;  
  
public class CacheTest {  
  
 private Map<String, Object> myAwesomeCache = new HashMap<String, Object>(100);  
   
 public Object getData(String id){  
    
  Object objToReturn = null;  
    
  if(myAwesomeCache.containsKey(id)){  
   objToReturn = myAwesomeCache.get(id);  
  }else{  
   // retrieve from the database and populate the in memory cache map  
  }  
    
  return objToReturn;  
 }  
}  

This is just a very basic level implementation to put out the idea across that we sometimes do use Maps to construct in-memory caching implementations. The fact that we have to note is that though there is nothing intrinsically wrong with this implementation, in an instance where your application is running low on memory, it would be a ideal if the garbage collector could remove this from memory to free up some for the other processes that need it. But since this map is a strong reference, there is no way the garbage collector can mark this reference as eligible for collection. A better solution would be to change the caching implementation from HashMap to a WeakHashMap.

The Javadoc specifies the following about the WeakHashMap;

         “A hashtable-based Map implementation with weak keys. An entry in a WeakHashMap will   automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.”

So in retrospect, I believe whenever you are in need of an in-memory caching implementation and memory is of utmost importance to you, using a WeakHashMap would be beneficial.

That concludes my findings on the Reference package and I invite you all to share your experience in this regard which is highly appreciated.

Cheers

Reference: Understanding Java Weak References   from our JCG partner Dinuka Arseculeratne  at the My Journey Through IT  blog

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s