如果 Get<>ArrayElements 对应的 Release<>ArrayElements 模式是 JNI_COMMIT,我们是否应该删除/释放指针数组?

问题描述 投票:0回答:2

当调用JNI函数

Get<PrimitiveType>ArrayElements
时,它会返回一个C
JNI NativeType
指针数组,它可能是原始jarray的副本,或者直接指向jarray原始值的指针。

它还有一个相应的

Release<PrimitiveType>ArrayElements
当模式为
0
JNI_ABORT
并且如果
jboolean
输出
*isCopy
被设置为
JNI_TRUE
时释放缓冲区,但如果模式是
JNI_COMMIT
.

所以我的问题是如果我们将相应的

free
模式设置为delete[]
,我们是否应该
Get<PrimitiveType>ArrayElements
/Release<PrimitiveType>ArrayElements
当我们完成它时由
JNI_COMMIT
返回的指针,因为这种模式不释放缓冲区?

JNI_COMMIT 复制内容但不释放元素缓冲区


[编辑]

糟糕的是我没有马上看到

Get<PrimitiveType>ArrayRegion
不返回数组指针,我更新了我原来的第二个问题作为主要问题。

c++ java-native-interface
2个回答
3
投票

我们应该释放/删除[]

Get<PrimitiveType>ArrayRegion
返回的指针吗?

该操作是一个复制操作,它将数组中的some数据复制到调用者提供的缓冲区中。它不“获取”或数组,也不返回指针。 (文档说返回类型是

void
。)

此外,与

Get<PrimitiveType>ArrayElements
不同,文档没有提及发布或免费方法,任何需要发布或免费的东西。

但是,调用者负责在

Get<PrimitiveType>ArrayRegion
调用中提供的缓冲区的任何内存管理。


如果我们将相应的

Get<PrimitiveType>ArrayElements
模式设置为
Release<PrimitiveType>ArrayElements
,我们是否应该释放/删除[]由
JNI_COMMIT
返回的指针,因为这种模式也不释放缓冲区?

文档不是 100% 清楚,但我的阅读是你 do 在这种情况下需要释放/删除缓冲区。请注意,文档说明:

“其他选项 [例如

JNI_COMMIT
] 使程序员可以更好地控制内存管理,应格外小心使用。”


0
投票

你永远不应该在

Get<PrimitiveType>ArrayElements
返回的数组指针上调用 free / delete[],无论本机数组“查看”Java 数组还是 JVM 分配的副本。当你完成这个数组时,你应该调用
Release<PrimitiveType>ArrayElements
,使用 mode
0
JNI_ABORT
.

但是在

Get…
和最终的
Release…
之间,您可能需要同步数组的本机端和 Java 端。这是通过使用
mode=
Release… 调用
JNI_COMMIT
来实现的。这样,您可以在最终
release 原生数组之前任意多次调用 Release…

注意最后你的JNI代码也要释放对Java数组的引用

© www.soinside.com 2019 - 2024. All rights reserved.