Wednesday, May 16, 2012

How are SoftReferences collected by JVMs in practice?


I have two separate caches running in a JVM (one controlled by a third party library) each using soft references. I would prefer for the JVM to clear out my controlled cache before the one controlled by the library. The SoftReference javadoc states:




All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError. Otherwise no constraints are placed upon the time at which a soft reference will be cleared or the order in which a set of such references to different objects will be cleared. Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.



Direct instances of this class may be used to implement simple caches; this class or derived subclasses may also be used in larger data structures to implement more sophisticated caches. As long as the referent of a soft reference is strongly reachable, that is, is actually in use, the soft reference will not be cleared. Thus a sophisticated cache can, for example, prevent its most recently used entries from being discarded by keeping strong referents to those entries, leaving the remaining entries to be discarded at the discretion of the garbage collector.




How do common JVM implementations, especially HotSpot, handle SoftReferences in practice? Do they "bias against clearing recently-created or recently-used soft references" as encouraged to by the spec?


Source: Tips4all

1 comment:

  1. Whatever the answer is, relying on a particular strategy would make your software unreliable because every JVM implementation may be different. Even for a given JVM, configuring it differently may alter the exact strategy and break your software. In short summary, it is an error to rely on a particular strategy.

    What type of resource is your cache managing? If its a pure heap allocated object, then the strategy should not matter. Using a ReferenceQueue might help to get you notified when a SoftReference gets cleared, though.

    If the resource type is not only a heap allocated object, then you must require your users to call an explicit release method, i.e. Closeable.close(). In order to protect against "forgotten" calls to this release method, you may consider implementing a finalize() method, but beware of its side effects. For more information about this, I recommend to read "Item 7: Avoid finalizers" from Joshua Bloch's "Effective Java (2nd Edition)".

    ReplyDelete