SoftReference incorrect javadoc?
michael at michaelpollmeier.com
Wed Apr 17 01:59:09 UTC 2019
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
That's great to know, but is it worth updating the javadocs of older
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).
java -Xms256m -Xmx256m SoftRefTest
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
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
openjdk version "1.8.0_212"
java version "1.8.0_144" (oracle)
openjdk version "126.96.36.199" (zulu build)
openjdk version "10.0.2" 2018-07-17 (zulu build)
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.
>> On 16/04/2019 12:14 pm, Michael Pollmeier wrote:
>>>> 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.
More information about the core-libs-dev