Understanding Java References
Join the DZone community and get the full member experience.
Join For FreeI 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.
From http://dinukaroshan.blogspot.com/2012/01/understanding-java-references.html
Opinions expressed by DZone contributors are their own.
Comments