6

I assumed, I understood how Bytebuffer and DirectByteBuffer differs until i read a artical on IBM documentation, metioning :

"Direct ByteBuffer objects clean up their native buffers automatically but can only do so as part of Java heap GC"

https://www.ibm.com/developerworks/library/j-nativememory-linux/

Now I am not able to understand this line, as it says DirectByteBuffer does cleaning as part of Java heap GC.

IFAIK, Java Heap GC only do clean up in java heap(where DirectByteBuffer is not allocated). It(GC) is no aware of native memory(where DirectByteBuffer is allocated).

Please help me understand this line, or if there is gap in my understanding

Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
Ankush G
  • 989
  • 9
  • 14

4 Answers4

9

When you create an instance of java.nio.DirectByteBuffer you, essentially, have 2 parts:

  • Usual java object of type java.nio.DirectByteBuffer, which is allocated on the heap
  • The actual byte buffer that you wanted, which is allocated by the constructor of the aforementioned java object off the heap

In addition, the constructor of java.nio.DirectByteBuffer registers a runnable of type java.nio.DirectByteBuffer.Deallocator, which is a private static class. This runnable is executed when this instance of java.nio.DirectByteBuffer is cleaned up by the GC. And it is the task of this Deallocator to release the native byte buffer. RTFS! :)

Nikem
  • 5,716
  • 3
  • 32
  • 59
1

With 11 (and presumably onwards), at some time after that the GC has detected that the DirectByteBuffer has become phantom-reachable, the reference handler thread will run the cleanup code in the DirectByteBuffer that deallocates the native memory area.

You can call the cleanup yourself by calling Unsafe like so:

Unsafe u = Unsafe.getUnsafe()
ByteBuffer bb = ByteBuffer.createdDirect(100);
u.invokeCleaner(bb);

I do feel that doing all this should be avoided if you can.

Erik
  • 2,013
  • 11
  • 17
0

Java Heap GC only do clean up in java heap

In the HotSpot JVM, when the DirectByteBuffer is cleaned up, the memory associated with is freed or unmapped.

Note: this is no different to other objects which are proxies for external resources such as Sockets, File streams, GUI components.

What is different is the resources isn't Closeable. This might not be available for a number of reasons, most likely because accessing a memory region after it has been freed can corrupt memory or crash the JVM. With the Hotspot JVM it is possible to free/unmap the memory deterministically with

((DirectBuffer) buffer).cleaner().clean();

However, this is undocumented and a) not the same across JVMs, b) use at own risk, c) might not be available in future.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • All these days, I was thinking, as Direct Byte Buffer is on non java heap area, it is never de-allocated which creates memory leaks hence avoid it unless you are using same DirectByteBuffer throughout the application lifetime i.e. when you don't need to create multiple DirectByteBuffer. If it, even being in non heap region, is de-allocated then what is the disadvantage of using this Direct Byte Buffer? – Ankush G Oct 19 '16 at 11:56
  • @shyampatil the main disadvantage is you have to store your data as bytes (or primitives) and it not thread safe. Working with Java Objects is much more natural. BTW depending on what you are doing off heap byte buffers are faster than on heap byte buffers. – Peter Lawrey Oct 19 '16 at 13:46
-1

It says DirectByteBuffer does cleaning as part of Java heap GC.

No it doesn't. It says 'Direct ByteBuffer objects clean up their native buffers automatically, but can only do so as part of Java heap GC'. Not the same thing at all.

IFAIK, Java Heap GC only do clean up in java heap

Correct, but IBM is talking about direct ByteBuffers doing the cleaning, not GC.

(where DirectByteBuffer is not allocated).

There is no such thing as DirectByteBuffer. There are direct ByteBuffers, which are allocated on the heap, except for their direct part, which is a native byte array.

It (GC) is no aware of native memory (where DirectByteBuffer is allocated).

Wrong again, see above.

There is no mystery to this. Direct ByteBuffers can have a finalize() method that invokes cleanup of the native byte array when invoked by GC.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • so just for my clarification: "the ByteBuffer object is always created on Heap, irrespective of the location of byte array of that ByteBuffer Object" e.g. in case of Direct and Non Direct Byte Buffer an Object is always created on java heap which looks like: `Class ByteBuffer{} – Ankush G Oct 19 '16 at 11:47
  • so just for my clarification: "the ByteBuffer object is always created on Heap, irrespective of the location of byte array of that ByteBuffer Object" e.g. in case of Direct and Non Direct Byte Buffer an Object is always created on java heap which looks like: `Class ByteBuffer{ byte[] arr; }` now in case of Direct Byte Buffer, this byte array 'arr' will have reference to the native memory location whereas in case of NonDirect Byte Buffer this byte array 'arr' will refer to java heap memory location" Is it? – Ankush G Oct 19 '16 at 11:51