java即使GetPrimitiveArrayCritical失败,我是否应该始终调用ReleasePrimitiveArrayCritical?
我想从JNI代码访问char[],如果可能的话,避免复制。现在,我要做的是:
void my_function(JNIEnv *env, jcharArray array) {
jsize len = env->GetArrayLength(array);
if (env->ExceptionCheck() == JNI_TRUE)
return;
jchar *chars = env->GetPrimitiveArrayCritical(array);
// process chars and len
env->ReleasePrimitiveArrayCritical(array, chars, JNI_ABORT);
}
根据JNI documentation,GetPrimitiveArrayCritical
可能在“抛出”OOM异常时返回NULL
。但是,它们没有明确说明在这种情况下是否仍应调用ReleasePrimitiveArrayCritical
我该怎么办
jchar *chars = env->GetPrimitiveArrayCritical(array);
if (chars == NULL)
return;
或
jchar *chars = env->GetPrimitiveArrayCritical(array);
if (chars != NULL) {
// process chars
}
env->ReleasePrimitiveArrayCritical(array, chars, JNI_ABORT);
# 1 楼答案
我对文档的理解是,如果你没有得到你的“chars”,就没有什么可以发布的。通过调用release,您不会释放“数组”,而是释放与数组关联的元素。如有必要,它会释放“字符”(仅当它是副本时)
如果您是“阵列”的所有者,则需要释放“阵列”。在这种情况下: {code}
此外,我还发现了这个示例生产代码,它仅在返回的指针不为null时显式调用ReleasePrimitiveArrayCritical
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/libjpeg_turbo/turbojpeg-jni.c&q=GetPrimitiveArrayCritical&sq=package:chromium&l=365
# 2 楼答案
查看openjdk code,似乎需要调用
ReleasePrimitiveArrayCritical
来解锁在GetPrimitiveArrayCritical
调用中锁定的GC(GC_locker::unlock_critical
)似乎java数组和本机数组参数也被忽略,而且
GetPrimitiveArrayCritical
无论如何都不会返回NULL但这仅对openjdk 7有效
# 3 楼答案
ReleasePrimitiveArrayCritical(…, NULL, …)
将失败。但我必须承认,我从未经历过GetPrimitiveArrayCritical()
返回NULL。遗憾的是,没有办法有条件地请求字节,即没有JNI函数GetPrimitiveArrayCriticalNoCopyOrFail()