Release<>ArrayElements用JNI_COMMIT模式时,是否需释放Get返回的指针?
JNI_COMMIT模式下Release后是否需要手动释放Get返回的指针?
结论:绝对不要手动调用free()或delete[]去释放Get<PrimitiveType>ArrayElements返回的指针
原因如下:
- 内存管理权限完全在JNI层(JVM):
Get<PrimitiveType>ArrayElements返回的指针,要么是直接指向Java数组的内部内存(非用户分配),要么是JVM为你分配的副本。无论哪种情况,你都没有这个内存的所有权。 JNI_COMMIT的作用仅为同步修改:这个模式只会把你对指针的修改同步回Java数组,但不会释放JVM分配的缓冲区(如果是副本)。但即便如此,你也不能手动释放——后续你仍可继续使用该指针,或最终通过0(正常释放+同步)或JNI_ABORT(放弃修改+释放)模式调用Release函数完成收尾。- 手动释放会引发严重错误:如果指针指向JVM内部内存,手动free会直接破坏JVM的内存结构;如果是JVM分配的副本,手动free会导致JVM后续尝试释放时出现double free错误,进而引发崩溃或不可预知的行为。
正确流程示例:
// 获取指针 jintArray javaArray = ...; jboolean isCopy; jint* nativePtr = env->GetIntArrayElements(javaArray, &isCopy); // 修改指针指向的内容 nativePtr[0] = 123; // 同步修改到Java数组,但不释放指针(JNI_COMMIT) env->ReleaseIntArrayElements(javaArray, nativePtr, JNI_COMMIT); // 继续使用指针做其他修改 nativePtr[1] = 456; // 最终释放指针(此时用0或JNI_ABORT) env->ReleaseIntArrayElements(javaArray, nativePtr, 0);
内容的提问来源于stack exchange,提问作者0xdeadbeef
相关产品推荐
相关产品推荐

