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