Hi Per, While testing different JVMs I realized that it's fixed in openjdk 11, e.g. openjdk version "11.0.1" 2018-10-16 LTS (zulu build), maybe by this commit: https://hg.openjdk.java.net/jdk/jdk/rev/6464882498b5 That's great to know, but is it worth updating the javadocs of older versions?
To reproduce it I attached a simple SoftRefTest.java to easily reproduce it. It allocates (only) softly referenced objects that occupy some heap, occasionally printing counts (instantiated, finalized, free heap). Usage: javac SoftRefTest.java java -Xms256m -Xmx256m SoftRefTest Output: 100000 instances created; free=212M 200000 instances created; free=181M 300000 instances created; free=152M 400000 instances created; free=121M 500000 instances created; free=93M 600000 instances created; free=61M 700000 instances created; free=33M Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Instance.<init>(SoftRefTest.java:27) at SoftRefTest.main(SoftRefTest.java:12) Interpretation: It doesn't free any of the only softly referenced objects, resulting in an OutOfMemoryError, contradicting the 'guarantee' in the javadoc. Workaround: if you additionally configure `-XX:SoftRefLRUPolicyMSPerMB=0`, it finalizes them and doesn't run out of memory. Tested with: openjdk version "1.8.0_212" java version "1.8.0_144" (oracle) openjdk version "9.0.4.1" (zulu build) openjdk version "10.0.2" 2018-07-17 (zulu build) Cheers Michael On 16/04/19 6:27 pm, Per Liden wrote: > Hi Michael, > > On 4/16/19 4:19 AM, David Holmes wrote: >> Hi Michael, >> >> Re-directing to core-libs-dev and hotspot-gc-dev. >> >> Thanks, >> David >> >> On 16/04/2019 12:14 pm, Michael Pollmeier wrote: >>> Quoting >>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >>> >>> >>> >>>> All soft references to softly-reachable objects are guaranteed to have >>> been cleared before the virtual machine throws an OutOfMemoryError >>> >>> That statement was true when soft references were first introduced in >>> java 1.2, but from java 1.3.1 the jvm property >>> `-XX:SoftRefLRUPolicyMSPerMB` was introduced. > > That statement is still true. When the GC gets into a situation where it > is having trouble satisfying an allocation, then SoftRefLRUPolicyMSPerMB > will be ignored and all soft references will be cleared, before the GC > gives up and throws an OOME. > >>> It defaults to 1000 (milliseconds), meaning that if there’s only 10MB >>> available heap, the garbage collector will free references that have >>> been used more than 10s ago. I.e. everything else (including young >>> softly reachable objects) will *not* be freed, leading to an >>> OutOfMemoryError, contradicting the above quoted 'guarantee'. >>> >>> That's also the behaviour I observed on various JREs. Would you agree, >>> i.e. should I propose an updated doc? > > Could you elaborate on what kind of test you did to come to this > conclusion? Preferably provide a re-producer. In OOME situations, if a > SoftReference isn't cleared, it is typically because you have > unknowingly made it strongly reachable. > > cheers, > Per >