有没有办法通过JNI将Java数组传递给C而不复制它?

Eld*_*der 8 java java-native-interface

我知道使用GetDoubleArrayElements,JVM决定是否复制Array的元素.在这种情况下,有没有办法避免复制?如果没有,有没有其他方法从Java转移到C而不复制?我传递的是非常大的阵列,我希望我可以避开副本.谢谢

Til*_*ilo 6

JNI指导说:

在 JDK/JRE 1.1 中,程序员可以使用 Get/ReleaseArrayElements 函数来获取指向原始数组元素的指针。如果VM支持pinning,则返回原始数据的指针;否则,复制一份。

JDK/JRE 1.3 中引入的新函数允许本机代码获取指向数组元素的直接指针,即使 VM 不支持固定。

这些“新功能”是GetPrimitiveArrayCriticalReleasePrimitiveArrayCritical完全禁止其垃圾回收,并有由此小心使用。所以总而言之,这是一个 VM 问题而不是 API 问题。不要忘记,不固定垃圾收集器可能会决定压缩堆并物理移动数组,因此直接指针毕竟没有什么用处。

正如彼得建议您可以使用 ajava.nio.DoubleBuffer而不是使用数组。JNI 函数

void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
Run Code Online (Sandbox Code Playgroud)

允许您访问它。

  • 这真的取决于您的用例。当您的数据是 Java 代码的输出和 C 代码的输入时,一种考虑可能是使用“GetPrimitiveArrayCritical”或“GetArrayElements”。当您的数据以另一种方式流动时,您将使用“GetDirectBufferAddress”。 (3认同)