[Tip of the Week] What is a Soft Reference Cache Anyway?

CacheBox contains a number of different cache providers ranging from EHCache to Railo’s Memcached. There is also a provider implemented in ColdFusion simply called the “CacheBox Provider” and two of it’s stores are the ConcurrentStore and the ConcurrentSoftReferenceStore. You may have wondered what the “soft reference” part means and why you would want to use it. If that’s you, here’s some history and explanation.

In Java, Whether or not an object is garbage collected from the heap is dependent on whether or not it has “GC roots” or garbage collector roots. A GC root is a reference chain in memory that ends with a root object that is exempt from garbage collection. An example would be a thread. It is represented by an object on the heap, but it can run forever and will never be garbage collected. Likewise, any objects that thread has “hard” references to will also not be GC’d and anything those objects in turn have references to and so on. So, a chain of hard references back to a GC root will keep you on the heap.

So, why does this matter? A JVM has a static upper bound in regards to heap space and when you’re dealing with an in-process cache, you run the risk of putting so many objects in the cache that the JVM runs out of space and you get an out-of-memory error. The concurrentStore uses a good old hard reference. CFML only has hard references. When you set a = b that’s always a hard reference. Java has additional types of references that can exist. Soft references, phantom references and weak references. They are represented as a class which sits between the referencing object and the object being referenced. They provide a way for the referenced object to be accessed, but they don’t hold a “hard” reference meaning that at any time, the garbage collector can come along, and if it needs RAM badly, it can collect any objects with a weak reference to them. Obviously, you would only use this reference type if you were ok with your object not existing the next time you went and looked for it.

So the concurrent soft reference cache uses a concurrent hash map (like a struct, but with better performance due to it’s granular internal locking and no-locking reads) which is full of soft reference objects, that in turn point to the real items you’ve placed in the cache. When garbage collection runs, it has the option to remove one or all of those items from memory if it wishes. Every time CacheBox wants to retrieve something from a soft reference store, it has ask the Java soft reference object to hand it over. When the cache is reaped, it checks for items which have been garbage collected and don’t exist any longer and expires them. So basically, the soft reference store help protect your JVM, but it has to do a little more work to get an item.

Now, that being said, I have rarely had items be garbage collected from a softreference cache provider. This is in part to the fact that I always monitor my heap sizes and make sure I have plenty of headroom.

Here’s some extra reading if you’re still curious about the Java classes:

And here’s some more info about CacheBox providers and stores:

P.S. Another way you can protect your heap is to set a JVM memory threshold in your CacheBox provider’s config. (This is only available for the internal “CacheBox” providers). Every time CacheBox goes to set an object in the cache, it will check the percentage of free memory, and if it’s too small, it will evict an item or items prior to setting the new one in based on the eviction policy and eviction count.



ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com