有没有办法通过JNI将Java数组传递给C而不复制它?
我知道使用GetDoubleArrayElements,是JVM决定是否复制数组元素。在这种情况下,有没有办法避免复制?如果没有,是否有其他方法可以不复制而从Java传输到C?我正在传递非常大的数组,我希望能够避免复制。 谢谢经理说: 在JDK/JRE 1.1中,程序员可以使用Get/ReleaseArrayElements函数获取指向基元数组元素的指针如果VM支持固定,则返回指向原始数据的指针;否则,将制作一份副本 JDK/JRE 1.3中引入的新函数允许本机代码获得指向数组元素的直接指针,即使VM不支持固定 这些“新函数”是有没有办法通过JNI将Java数组传递给C而不复制它?,java,java-native-interface,Java,Java Native Interface,我知道使用GetDoubleArrayElements,是JVM决定是否复制数组元素。在这种情况下,有没有办法避免复制?如果没有,是否有其他方法可以不复制而从Java传输到C?我正在传递非常大的数组,我希望能够避免复制。 谢谢经理说: 在JDK/JRE 1.1中,程序员可以使用Get/ReleaseArrayElements函数获取指向基元数组元素的指针如果VM支持固定,则返回指向原始数据的指针;否则,将制作一份副本 JDK/JRE 1.3中引入的新函数允许本机代码获得指向数组元素的直接指针,即
GetPrimitiveArrayCritical
和ReleasePrimitiveArrayCritical
,它们完全禁用垃圾收集,因此必须小心使用。总之,这是一个VM问题,而不是API问题。不要忘记,在不固定垃圾收集器的情况下,垃圾收集器可能会决定压缩堆并实际移动数组,因此直接指针毕竟没有什么用处
正如Peter所建议的,您可以使用java.nio.DoubleBuffer
而不是使用数组。JNI函数
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
允许您访问它。您可以使用DoubleBuffer包装直接字节缓冲区。这更新了一个可以直接在Java/C中使用的内存区域。我想知道首选哪个,byte[]和
GetPrimitiveArrayCritical
还是ByteBuffer和GetDirectBufferAddress
?这取决于您的用例。当数据是Java代码的输出和C代码的输入时,可以考虑使用GetPrimitiveArrayCritical
或GetArrayElements
。当数据以另一种方式流动时,您将使用GetDirectBufferAddress
。