Understanding Java Weak References

I could not pay attention to the blog in the recent times and first and foremost I must apologize for not staying in touch with you all in the world of technology. I recently stumbled upon the java.lang.ref package which was available since Java 1.2 but ironically i got to know about it just a few days back. Going through a few articles explaining about the various reference types and the java doc as well, I was very much intrigued and was anxious to get my hands dirty with some reference related code.

Im not going to talk about each reference class available within the java.lang.ref package as it is already very well explained here. Let us take a look at the following code snippet which I wrote to understand the basic operation of a WeakReference.

import java.lang.ref.WeakReference;  
import java.util.HashMap;  
import java.util.Map;  
  
public class ReferencesTest {  
  
 private WeakReference<Map<Integer, String>> myMap;  
  
 public static void main(String[] args) {  
  new ReferencesTest().doFunction();  
 }  
  
 private void doFunction() {  
  
  Map<Integer, String> map = new HashMap<Integer, String>();  
  myMap = new WeakReference<Map<Integer, String>>(map);  
  
  map = null;  
  int i = 0;  
  while (true) {  
   if (myMap != null && myMap.get() != null) {  
    myMap.get().put(i++, "test" + i);  
  
    System.out.println("im still working!!!!");  
   } else {  
  
    System.out  
      .println("*******im free*******");  
  
   }  
  
  }  
 }  
}  

First I have defined a weak reference instance variable to which I assign an instance of a HashMap initialized within the doFunction() method. Then data is input to the map via the weak reference instance and not directly through the concrete instance of the hashmap we created. We check for the map being null due to the fact of the way WeakReferences work.

During the execution of the program, a weak reference will be the first to be garbage collected if there are no soft or strong references binding to it. So if memory is considerably low, or when and if the garbage collector deems appropriate, the weak reference is garbage collected and this is why I have included the else statement within my code to show the occurrence of that situation. Run this by setting minimum –Xms and –Xmx to understand how it works since otherwise you will have to wait a longer period to get an out of memory exception. And then change the WeakReference implementation to a SoftReference implementation and see that the program actually crashes after a few iterations. This is due to the fact that SoftReferences only gurantee to clean up memory just before a OutOfMemory error occurs. But with the WeakReference, the program continues to function without halting because it is almost always eligible for garbage collection and we can reinitialize the cache and continue to repopulate our cache.

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

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

2 Responses to "Understanding Java Weak References"

  1. DmitrySemenov says:

    I’ve tried your test.
    1. Using WeakReference GC eagers ro clear weakly reffered objects, what is actually happens:
    im still working!!!!6062048im still working!!!!6062048*******im free*******8811200*******im free*******8811200
    So you can use WeakReference to 
    2. Using SoftReference hasn’t caused out of memory  (jdk1.6.0_29). Looks like GC is clearing the memory just before OutOfMemotyError, but no Error raised.
    i added following code to log
    System.out.println(“im still working!!!!” + Runtime.getRuntime().freeMemory());
    System.out.println(“*******im free*******” + Runtime.getRuntime().freeMemory());
    here is an result:
    ….
    im still working!!!!1114136
    im still working!!!!9254512
    *******im free*******9252432
    *******im free*******9252432
    ..
    there was no exception raised and programm continued to run Also Java Doc says that it can be cleared by GC not only before OutOfMemoryError but earlier. And i think that it’s some algorithm used by GC to make a decision. I think GC analyse the time object hasn’t been used and used memory ratio.  So as i result SoftReference is more strong then WeakReference, and more suitable for Cache implementations, as it guaranties that softly referenced object will be GCed before OutOfMemotyError

  2. Pepito says:

    Using a WeakHashMap as a cache is not a good idea. A FIFO data structure is usually a better idea, as you usually want items to stay in the cache for some time regardless of whether there are or not strong references to them outside the cache.

Leave a Reply


× nine = 81



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close