Search code examples
javajava-native-interface

JNI: best way to pass global variable to-and-fro with smallest overhead?


So I have a global integer array declared within my Java code which is allocated just once that I'd like to be able to cache a raw pointer to within the initialization routine of my JNI code. Is this even possible (or does the VM reserve the right to hand me a copy of the array)? If not, could I instead allocate the memory (say via NewIntArray) from the JNI side, then pass that to the Java code just once to be cached?

Any suggestions would be appreciated!


Solution

  • Arrays, just like all other objects, can be moved around in the heap memory by the garbage collector. If you want a block of data that won't be moved (and you can cache a pointer into) you need to use an off-heap ByteBuffer.

    In JNI you can create one using the NewDirectByteBuffer function: reserve memory outside of the Java heap using malloc and call this function to create a ByteBuffer object that wraps the memory.

    If you want to create the buffer from the Java side, you have ByteBuffer.allocateDirect. The JNI function GetDirectBufferAddress then returns the pointer to the raw memory buffer.