Hi,

upon reading [1] I tried a similar scenario, but where OOME are caused by "Java heap space" exhaustion rather than by VM limits.


import java.lang.ref.SoftReference;
import java.text.DecimalFormat;
import java.util.ArrayList;

public class Softly {

    public static void main(String[] args) {
        var size = Integer.parseInt(args[0]);
        var format = new DecimalFormat("#,###");
        var news = 0;
        var ref = new SoftReference<>(new ArrayList<>());
        for (;;) {
            byte[] b = null;
            try {
                b = new byte[size];
                ++news;
                ref.get().add(b);
            } catch (NullPointerException __) {
System.out.format("totSize = %20s, allocations = %d\n", format.format((long) news * size), news);
                ref = new SoftReference<>(new ArrayList<>());
                ref.get().add(b);
            } catch (OutOfMemoryError e) {
                if (ref.refersTo(null)) {
throw new AssertionError("allocations = %d".formatted((news)), e);
                }
                throw new AssertionError("non-null referent", e);
            }
        }
    }

}


E.g.,
java -XX:+UseG1GC -Xms1g -Xmx1g -cp ... Softly 800000000


Depending on the collector and how tight the heap is, I sometimes observe a "Java heap space" OOME but then the referent of ref is null. I never observed a OOME with a non-null referent for ref. Hence, in scenarios where OOME are caused by heap exhaustion, soft refs seem to work as advertised.

Tried on AdoptOpenJDK-16.0.1+9 with SerialGC, ParallelGC, G1GC, ZGC and ShenandoahGC with either -Xms1g/-Xmx1g or -Xms2g/-Xmx2g (small heaps) and various byte[] sizes.

Thus, the current wording in SoftReference's javadoc:

"All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError."

could be amended to read:

"All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError caused by Java heap space exhaustion."


Greetings
Raffaello

----

[1] https://bugs.openjdk.java.net/browse/JDK-8267222

Reply via email to