Is there any way to pass a Java Array to C through JNI without making a copy of it?
I understand that using GetDoubleArrayElements, it is the JVM who decides whether or not to copy the elements of Array. In this case, is there any way to avoid the copy? If not, is there an other way to transfer from Java to C without copying? I'm passing very big Arrays, and I wish I could avoid the copy. Thanks
Solution 1:
The JNI guide says:
In JDK/JRE 1.1, programmers can use Get/ReleaseArrayElements functions to obtain a pointer to primitive array elements. If the VM supports pinning, the pointer to the original data is returned; otherwise, a copy is made.
New functions introduced in JDK/JRE 1.3 allow native code to obtain a direct pointer to array elements even if the VM does not support pinning.
These "new functions" are GetPrimitiveArrayCritical
and ReleasePrimitiveArrayCritical
which disable garbage collection completely and have thus to be used with care. So in summary it is a VM problem rather than an API problem. Don't forget that without pinning the garbage collector might decide to compact the heap and physically move your array, so the direct pointer would be of little use after all.
As Peter suggested you could work with a java.nio.DoubleBuffer
instead of using arrays. The JNI function
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
allows you to access it.