Monday, December 1, 2014

JDK 8: When Softly Referenced Objects Are Flushed?

There are four different degrees of reference strength in Java language:[1]
  1. Strong
    • StringBuffer strongRef = new StringBuffer();
  2. Soft
    • SoftReference softRef = new SoftReference(obj);
  3. Weak
    • WeakReference weakRef = new WeakReference(widget);
  4. Phantom
    • PhantomReference phantomRef =new PhantomReference(bool,rq);
in order from strongest to weakest.

In this article, we will focus on softly referenced objects and when they will be flushed by Garbage Collector (GC) in HotSpot.


SoftReference vs WeakReference


A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while.

SoftReferences aren't required to behave any differently than WeakReferences, but in practice softly reachable objects are generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache since you can let the garbage collector worry about both how reachable the objects are and how badly it needs the memory they are consuming.

When Softly Referenced Objects Are Flushed?


Prior to version 1.3.1, the Java HotSpot VMs cleared soft references whenever it found them. Starting with 1.3.1, softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap. This value can be adjusted using the -XX:SoftRefLRUPolicyMSPerMB flag, which accepts integer values representing milliseconds. For example, to change the value from one second to 2.5 seconds, use this flag:
-XX:SoftRefLRUPolicyMSPerMB=2500

When, exactly, is a soft reference freed?  Here are the factors to be considered:
  • First the referent must not be strongly referenced elsewhere
  • If the soft reference is the only remaining reference to its referent, the referent is freed during the next GC cycle only if the time it was last accessed is greater than (AmountOfFreeMemoryInMB * SoftRefLRUPolicyMSPerMB).
    • AmountOfFreeMemoryInMB is calculated differently for server and client VMs:
      • Server VM
        • Uses the maximum possible heap size (as set with the -Xmx option) to calculate free space remaining
          • -Xmx therefore has a significant effect on when soft references are garbage collected.
        • The general tendency is for the Server VM to grow the heap rather than flush soft references
      • Client VM
        • Uses the current heap size to calculate the free space
        • The Client VM will have a greater tendency to flush soft references rather than grow the heap

Conclusion

  • When to use SoftReference?
    • Soft references are used when the object in question has a good chance of being reused in the future,
      • For example, as a cache implementation
        • Soft references are essentially one large, least-recently-used cache
  • Performance consideration
    • The key to getting good performance from that cache is to make sure that it is cleared on a timely basis.
    • Eagerly vs. lazily reclaimation of softly referenced objects
      • You can tune how eagerly they are reclaimed by setting:
        • -XX:SoftRefLRUPolicyMSPerMB flag
          • Default is 1000 ms. Optimal setting depends on the applications and which GC is used.
          • This behavior is not part of the VM specification, however, and is subject to change in future releases. Likewise the -XX:SoftRefLRUPolicyMSPerMB flag is not guaranteed to be present in any given release.

References

  1. Understanding Weak References Blog (good)
  2. Frequently Asked Questions About the Java HotSpot VM
  3. HotSpot Virtual Machine Garbage Collection Tuning Guide
  4. Garbage-First Garbage Collector Tuning
  5. Other JDK 8 articles on Xml and More
  6. Tuning that was great in old JRockit versions might not be so good anymore
    • Trying to bring over each and every tuning option from a JR configuration to an HS one is probably a bad idea.
    • Even when moving between major versions of the same JVM, we usually recommend going back to the default (just pick a collector and heap size) and then redoing any tuning work from scratch (if even necessary).

No comments: