javaniobytebufferdirect-buffer

Releasing a direct buffer in java and possible pitfalls


we have the following piece of code:

long buffer = ((DirectBuffer) ByteBuffer.allocateDirect(256)).address(); 

It seems that there is no reference to direct buffer (as an object) on the thread's stack. So, it means that that object is phantom-reachable.

  • DirectByteBuffer becomes phantom-reachable.
  • Garbage collection is performed (in separate thread), DirectByteBuffer Java object is collected and an entry is added to the ReferenceQueue.
  • Cleaner thread reaches this entry and runs the registered clean-up action (in this case, it's java.nio.DirectByteBuffer.Deallocator object), this action finally frees the native memory.

The citation comes from: Java - When does direct buffer released?

So, it is possible that allocated memory that can be freed. However, we have a pointer to that, buffer of type long. Therefore it is possible that we've got SIGSEGV or something like that.

My question is:

Does it mean that we can hurt ourself using DirectBuffer in that manner?


Solution

  • Your assumption of danger here is correct, with a caveat.

    The backing buffer of the direct buffer can be freed at any point after the containing ByteBuffer object becomes eligible for garbage collection (the exact moment the native memory is freed is implementation dependent, but typically it happens approximately when finalizer for the ByteBuffer runs).

    From standard Java, this "dangling pointer" doesn't pose a real problem since it just a long like another other and you can't use unsafely. Of course if you pass it to some native or Unsafe code and try to use it as a pointer things can blow up.