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