Since it's out of jvm heap & gc, when does it released? Or, it remain until process termination?
I already checked:
But all the answers are blur, none answered it explicitly, does there have a clear answer? At least for Java 8 on 64-bit Linux.
As we said, the Direct Buffers are allocated to native memory space outside of the JVM’s established heap/perm gens. If this memory space outside of heap/perm is exhausted, the java.lang.OutOfMemoryError: Direct buffer memory Error will be throw.
DirectByteBuffer does not use old Java finalizers. Instead, it uses internal sun.misc.Cleaner API. It creates new thread and stores a PhantomReference to every DirectByteBuffer created (except duplicates and slices which refer to the primary buffer).
After all, there's no method to explicitly close or release them. The answer is that they get garbage collected like any other object, but with one twist: if you don't have enough virtual memory space or commit charge to allocate a direct buffer, that will trigger a full collection even if there's plenty of heap memory available.
When the DirectByteBuffer becomes phantom-reachable (that is, no strong, soft or weak references to the byte buffer exist anymore) and garbage collector sees this, it adds this buffer to the ReferenceQueue which is processed by Cleaner thread. So three events should occur: DirectByteBuffer becomes phantom-reachable.
DirectByteBuffer
does not use old Java finalizers. Instead, it uses internal sun.misc.Cleaner
API. It creates new thread and stores a PhantomReference
to every DirectByteBuffer
created (except duplicates and slices which refer to the primary buffer). When the DirectByteBuffer
becomes phantom-reachable (that is, no strong, soft or weak references to the byte buffer exist anymore) and garbage collector sees this, it adds this buffer to the ReferenceQueue
which is processed by Cleaner
thread. So three events should occur:
DirectByteBuffer
becomes phantom-reachable.DirectByteBuffer
Java object is collected and an entry is added to the ReferenceQueue
.java.nio.DirectByteBuffer.Deallocator
object), this action finally frees the native memory.So in general you have no guarantee when it's freed. If you have enough memory in the Java heap, garbage collector may not be activated for a long time. Also even when it's phantom-reachable, Cleaner thread may need some time to reach this entry. It might be busy processing previous objects which also used the Cleaner API. Note however that partial work-around is implemented in JDK: if you create new DirectByteBuffer
and allocated too much direct memory before, garbage collector might be called explicitly to enforce deallocation of previously abandoned buffers. See Bits.reserveMemory()
(called from DirectByteBuffer
constructor) for details.
Note that in Java-9 the internal Cleaner
API was rectified and published for general use: now it's java.lang.ref.Cleaner
. Reading the JavaDoc you may get more details how it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With