我使用NDK为Java分配大缓冲区:
allocNativeBuffer(JNIEnv* env, jobject cls, jlong size) {
void* buffer = malloc(size);
jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
jobject globalRef = env->NewGlobalRef(directBuffer);
return globalRef;
}
使用此缓冲区后,我将其解除分配:
freeNativeBuffer(JNIEnv* env, jobject cls, jobject globalRef) {
void *buffer = env->GetDirectBufferAddress(globalRef);
env->DeleteGlobalRef(globalRef);
free(buffer);
}
在Android 2.2上它工作正常,但在Android 4.0.3应用程序崩溃期间DeleteGlobalRef调用。我做错了什么?
答案 0 :(得分:1)
全局和本地引用的实现在ICS中进行了全面改进,旨在改进Java端的内存管理。在developers guide中查找解释。在developers blog中阅读更多内容。
简而言之,无论您在JNI函数中收到什么,包括globalRef
函数的freeNativeBuffer()
参数,都是本地参考。您可以在C代码中创建并保留全局引用,如下所示:
static jobject globalRef;
allocNativeBuffer(JNIEnv* env, jobject cls, jlong size) {
void* buffer = malloc(size);
jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
globalRef = env->NewGlobalRef(directBuffer);
return directBuffer;
}
freeNativeBuffer(JNIEnv* env, jobject cls, jobject localRef) {
void *buffer = env->GetDirectBufferAddress(localRef);
if (buffer == env->GetDirectBufferAddress(globalRef) {
/* we received the object that we saved */
env->DeleteGlobalRef(globalRef);
free(buffer);
}
}
PS 我发现stackoverflow discussion看起来像是您实验的灵感。请参阅answer,其中解释了首先无需创建和删除全局引用。