javagarbage-collectiondirect-buffer

DirectBuffer, deallocation


I allocated a direct buffer:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

I've read that:

Deallocating Direct Buffer Native Memory in Java for JOGL

but it doesn't answer directly.

To summarize:

  1. GC releases a directbuffer when GC will be launched and a directbuffer wasn't be referenced. In linked post it is written that:

When you know that a direct NIO buffer has become useless for you, you have to release its native memory by using its sun.misc.Cleaner (StaxMan is right) and call clean() (except with Apache Harmony), call free() (with Apache Harmony) or use a better public API to do that (maybe in Java >= 1.9, AutoCleaning that extends AutoCloseable?).

but I didn't see how to explicitly release of memory chunk. Ok, there exists a sun.misc.Cleaner and what?:

Cleaner c = new Cleaner()

  1. What is the purpose of using DirectBuffer instead of Unsafe.allocateMemory.


This solution (in this JEP, still a draft, probably not available in Java 1.9) is very promising, we won't need to use non public APIs.

public long memory(long index) {
    // The scope where the memory region is available
    // Implements AutoClosable but `close` can be called manually as well
    try (Scope scope = new NativeScope()) {
        // Allocate the actual memory area, in this case in the style of a "long-array"
        Pointer<Long> ptr = scope.allocate(
                    NativeLibrary.createLayout(long.class), numElements);

        // Get the reference to a certain element
        Reference<Long> ref = ptr.offset(index).deref();

        // Set a value to this element through the reference
        ref.set(Long.MAX_VALUE);

        // Read the value of an element
        return ref.get();
    }
}

It looks like smartpointers in C++, doesn't it?


Solution

  • but I didn't see how to explicitly release of memory chunk.

    Currently you can't in java because it wouldn't be safe. It could lead to use-after-free bugs. Approaches that would make it safe, e.g. virtual memory manipulation or safepoint gymnastics, are difficult, might cost some performance or may not work on all platforms.

    It is not impossible, but requires significant work. See JDK-4724038, its duplicates and linked mailing lists for the proposals that have accumulated over the years.

    What is the purpose of using DirectBuffer instead of Unsafe.allocateMemory.

    Safe access to stable memory locations that can be passed to native code without copying and without the need for object pinning (something not supported by hotspot).