JNI 啥时候需要复制原始类型的数组?

Posted

技术标签:

【中文标题】JNI 啥时候需要复制原始类型的数组?【英文标题】:when may JNI require copying arrays of primitive types?JNI 什么时候需要复制原始类型的数组? 【发布时间】:2012-07-02 17:40:47 【问题描述】:

我主要是一名 C++ 程序员,但我正在考虑将 Java 用于项目。出于性能原因,我将需要使用一些 SSE 内部函数(即使相对于普通 C++,这些函数也可以大大提高速度)。

据我了解,在 Java 中执行此操作的方法是使用 JNI 并在 C 中调用 SSE 内在函数。但是,我在 JNI 文档中读到的内容让我有点不安,因为它说 JVM 可能会或可能会不创建发送到 C 和返回的数组的副本。

假设一个最先进的实现,比如 OpenJDK 7,当我请求指向 byte[]、short[]、int[] 或 float[] 的指针时,我应该什么时候真正期望复制?

到目前为止,我发现的只是一些相互矛盾的说法。要被接受,一个答案必须说服我:例如提供证据或引用来源,而不仅仅是表达意见/猜测。

编辑

    链接到GetPrimitiveArrayCritical 正如我所提到的,在回答我的问题时假设 OpenJDK 7 是可以的。

【问题讨论】:

JNI 在设计上不提供对 Java 数组的原始数据的访问。上次我检查时,有单个元素访问,以及将一个区域从 Java 数组复制到一个非托管内存区域。我不明白怎么可能被复制。 @SevaAlekseyev 这不是真的:参见例如GetPrimitiveArrayCritical 嗯,我猜我有一个旧的 JNI 参考。 【参考方案1】:

我会考虑使用具有本机字节顺序的直接 ByteBuffer。这样做的好处是它以某种方式使用 C 空间内存,这意味着您无需复制它即可在 Java 中访问它(反之亦然)

【讨论】:

【参考方案2】:

到目前为止,我发现的只是一些相互矛盾的说法

不,这些声明并不矛盾,因为您所要求的是实现细节,并且取决于您将使用的 JDK 实现。 您不应该期望所有实现都具有相同的行为,您应该查看哪个实现了您想要的。 给你一个实现差异的例子,SUNJDK 将char[] 传递给C 代码空终止,而 IBM 没有。 因此,您应该深入研究实现和测试。至于你的问题,我不确定为什么不会发生数组复制,因为我相信内存区域完全发生了变化

【讨论】:

“SUN JDK 将 char[] 传递给 C 代码以 null 终止”令人难以置信。为什么会这样做? @EJP:我不知道。当我们从 SUN 切换到 IBM 时,虽然我们遇到了这个问题并且不得不为此更改 C 代码 @EJP:我必须为从 java 传递的所有字符串添加 '\0'。我不需要使用 SUN 来做。 太棒了。 GetStringUTFChars()? 它没有记录,所以你不应该依赖它。想知道我的代码是否可以:-|

以上是关于JNI 啥时候需要复制原始类型的数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改原始数组的情况下更改函数中的数组? [复制]

js中的类型和函数参数传递类型问题

在原始类型c ++中返回const或非常量有啥区别[重复]

JNI签名与数据匹配

java中int 和 Integer 有啥区别

RAW是啥数据类型