Or do I have to have a JNI helper function that calls env->NewDirectByteBuffer(buffer, size)?
Asked
Active
Viewed 3,264 times
8
-
1Have you looked at sun.misc.unsafe? It allows you to directly interact with memory. – assylias May 09 '13 at 15:42
-
I did take a look and didn't see of a way to create a direct byte buffer with sun.misc.unsafe. I did find a way to create a DirectByteBuffer and it's through reflection. Use java.lang.Class.getDeclaredConstructor to create a Constructor object, setAccessable to true and call newInstance with the appropriate parameters. Little janky but you don't have to write any JNI code. – Trevor Bernard May 12 '13 at 20:39
1 Answers
21
What I do is create a normal DirectByteBuffer and change it's address.
Field address = Buffer.class.getDeclaredField("address");
address.setAccessible(true);
Field capacity = Buffer.class.getDeclaredField("capacity");
capacity.setAccessible(true);
ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
address.setLong(bb, addressYouWantToSet);
capacity.setInt(bb, theSizeOf);
From this point you can access the ByteBuffer referencing the underlying address. I have done this for accessing memory on network adapters for zero copy and it worked fine.
You can create the a DirectByteBuffer for your address directly but this is more obscure.
An alternative is to use Unsafe (this only works on OpenJDK/HotSpot JVMs and in native byte order)
Unsafe.getByte(address);
Unsafe.getShort(address);
Unsafe.getInt(address);
Unsafe.getLong(address);

Peter Lawrey
- 525,659
- 79
- 751
- 1,130
-
Great answer, however I had to hack on it some to make it work, specifically Field address = Buffer.class.getDeclaredField("address"). – Erik Aug 23 '16 at 15:50
-
So here is a follow up to the original question since you are still paying attention. What's the best way to clean up the memory attached to the ByteBuffer in this manner? Will the ByteBuffer finalize free address or should the caller intervene and clean up the allocation? For the purposes of this question, assume I've written a JNI library with wrappers around malloc and free :) Probably deserves it's own question now that I've thought about it more. – Erik Aug 23 '16 at 22:23
-
@Erik who ever creates the memory should free it. If you need to call a special method you need to set up a Cleaner which can be called either deterministically or when the Buffer if GC if you do not. – Peter Lawrey Aug 23 '16 at 22:29
-
@Erik in Chronicle Bytes we have our own 64 bit wrapper for memory with additional functionality. We also have reference counting to allow memory to be freed on demand and a Cleaner in case it is not freed. – Peter Lawrey Aug 23 '16 at 22:31
-
Thanks for the quick reply! I will read up on Cleaner ( I'm a C programmer asked to do Java stuff, trying to spin up quick ). – Erik Aug 23 '16 at 22:32
-
@Erik a Cleaner can be added to an object which is called on garbage collection however it can also be called from code if you know you don't need the underlying resource. – Peter Lawrey Aug 23 '16 at 22:39
-
would it be possible to use the direct bytebuffer to access a java array? how would the address of the java array be found? – zcaudate Sep 20 '18 at 11:39