SoftReferences and java.lang.OutOfMemoryError: Direct buffer memory

Brett Okken brett.okken.os at gmail.com
Mon Dec 21 13:06:15 UTC 2020


I certainly understand why new long[Integer.MAX_VALUE] would throw an
OutOfMemoryError without clearing soft references. As you pointed out,
clearing soft references has no chance of helping, as the max array size is
reduced by some "header words".

I am a bit surprised by IntStream.range(0,
1000000000).boxed().collect(Collectors.toList()).size(); not clearing soft
references. Indeed, that does not match what I observe in jdk 11. Though it
does seem reasonable that if the jvm is able to determine that the result
would require more memory than the max heap, to just throw the OOME without
clearing soft references.

The case with direct ByteBuffer instances is a bit different. It is
possible that clearing references (especially if it were possible to only
clear references to direct ByteBuffer instances) would allow the OOME to be
avoided.

On Sun, Dec 20, 2020 at 3:50 PM Florian Weimer <fw at deneb.enyo.de> wrote:

> * Brett Okken:
>
> >  I am not sure if this is the correct mailing list for this question.
> > Please let me know if I should post it somewhere else.
> >
> > The javadoc for SoftReference states:
> >
> > All soft references to softly-reachable objects are guaranteed to have
> been
> > cleared before the virtual machine throws an OutOfMemoryError.
> >
> > But that is not quite true when it comes to allocating direct ByteBuffer
> > instances. Would it be possible to clear softly-reachable direct
> ByteBuffer
> > instances prior to throwing java.lang.OutOfMemoryError: Direct buffer
> > memory? This would make it much simpler (and safer) to implement a cache
> of
> > direct ByteBuffer instances for re-use.
>
> It's not true in other contexts, either:
>
> jshell> var r = new SoftReference<>(new Object() {});
> r ==> java.lang.ref.SoftReference at 57fa26b7
>
> jshell> r.get();
> $11 ==> $0 at 2f410acf
>
> jshell> new long[Integer.MAX_VALUE];
> |  Exception java.lang.OutOfMemoryError: Requested array size exceeds VM
> limit
>
> jshell> r.get();
> $13 ==> $0 at 2f410acf
>
> jshell> IntStream.range(0,
> 1000000000).boxed().collect(Collectors.toList()).size();
> |  Exception java.lang.OutOfMemoryError: Java heap space
>
> jshell> r.get();
> $15 ==> $0 at 2f410acf
>
> If taken literally, the specification requires that the
> OutOfMemoryError constructor has to clear all SoftReference objects,
> but that does not seem to happen.
>
> I think the intent is to encourage implementations not to report
> spurious OOMEs if they could be avoid by clearing soft references.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/nio-dev/attachments/20201221/f3ff1a94/attachment.htm>


More information about the nio-dev mailing list