SoftReferences and java.lang.OutOfMemoryError: Direct buffer memory
David Holmes
david.holmes at oracle.com
Tue Dec 29 06:57:55 UTC 2020
Hi Brett,
On 29/12/2020 5:16 am, Brett Okken wrote:
> I am cross posting this from the nio-dev mailing list.
>
> 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.
> As pointed out in the nio-dev thread, there are some exceptions to
> this when it is obvious that clearing soft references would not
> prevent the OOME. A simple example is trying to instantiate an array
> of size Integer.MAX_VALUE.
More accurately soft-references will be cleared before throwing an OOME
due to Java heap exhaustion. There are other things that can throw OOME
(like your array example, or "throw new OutOfMemoryError();") that don't
correspond to heap exhaustion and and so soft-reference clearing doesn't
enter the picture.
> My question, however, relates 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 may be a question for the GC guys as there is no exposed API for
directly requesting the GC undertake specific activities (System.gc() is
just a request and exactly what it will do is not specified.)
Generalizing, I presume what you are really looking for is a way to
force cleaners and/or finalizers to run to try and release direct buffer
memory. And I'm pretty sure that is a question that has been asked many
times so I'll let other re-state the response to that.
Cheers,
David
-----
> This would make it much simpler (and safer) to implement a cache of
> direct ByteBuffer instances for re-use. A potential use for this would
> be in sun.nio.ch.Util. JDK-8175230 introduced the ability to control
> the max size of direct ByteBuffer to cache, so as to avoid the OOME.
> There could be value in moving to a tiered caching strategy. The
> current approach of thread local values could be used for small
> instances.
> A second tier, for larger sizes (say >=64KB) could be shared among all
> threads and the cached instances be softly referenced. This would
> continue to avoid an OOME, but provide reuse for large direct
> ByteBuffers, which can be expensive to allocate/destroy.
>
> Thanks,
>
> Brett
>
More information about the core-libs-dev
mailing list