11

Assume in one hand we have a direct byte buffer created with env->NewDirectByteBuffer(). In other hand we have similar direct buffer, but created with ByteBuffer.allocateDirect(). Obviously both these objects should be managed by JVM in the same manner, including management of the backing native buffer, which in first case was provided by user, and in second case was allocated by JVM from native heap.

Of course JVM must free backing buffer during GC'ing of the second object (instantiated with ByteBuffer.allocateDirect()).

And my question: Will JVM try to deallocate buffer during GC'ing of the first object (instantiated with env->NewDirectByteBuffer()) ?

P.S. I've not found clear answer neither at JNI docs neither at SO. The most helpful info was here http://www.ibm.com/developerworks/library/j-nativememory-linux/index.html :

Direct ByteBuffer objects clean up their native buffers automatically but can only do so as part of Java heap GC — so they do not automatically respond to pressure on the native heap.

So it seems like JVM will free backing buffers during GC pass, but there is no any mentions about deallocator. Is it plain free() or something else.

1 Answer 1

13

When you are calling the JNI NewDirectByteBuffer(void* address, jlong capacity) a DirectByteBuffer object will be created, using the following constructor:

private DirectByteBuffer(long addr, int cap) {
    super(-1, 0, cap, cap);
    address = addr;
    cleaner = null;
    att = null;
}

Notice that the cleaner property is null.

If you create a DirectByteBuffer via ByteBuffer.allocateDirect() the cleaner property is set (see source code of DirectByteBuffer).

Now the cleaner is a utility object whose clean method is run when the buffer is garbage collected (see this explanation for details).

For the buffer constructed via ByteBuffer.allocateDirect() the cleaner deallocates the direct memory.

For the JNI constructed buffer no such operation is done. You need to free this memory yourself.

Sign up to request clarification or add additional context in comments.

2 Comments

Clear. Seems like Android uses the same approach. Android SDK has exhaustive comment: /** * Represents a block of memory we don't own. (We don't take ownership of memory corresponding * to direct buffers created by the JNI NewDirectByteBuffer function.) */
This was some of the best QnA recently, nobody seemed to know this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.