例如:执行
Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize()));
ByteBuffer buffer = allocateDirect(LARGE_NUMBER);
buffer=null;
System.gc();
Log.v("?", Long.toString(Debug.getNativeHeapAllocatedSize()));
给出两个对数,第二个数字至少比第一个大LARGE_NUMBER。
我该如何消除这个泄漏?
附加:
根据Gregory的建议在C++端处理alloc/free后,我定义了
JNIEXPORT jobject JNICALL Java_com_foo_bar_allocNative(JNIEnv* env, jlong size)
{
void* buffer = malloc(size);
jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
jobject globalRef = env->NewGlobalRef(directBuffer);
return globalRef;
}
JNIEXPORT void JNICALL Java_com_foo_bar_freeNative(JNIEnv* env, jobject globalRef)
{
void *buffer = env->GetDirectBufferAddress(globalRef);
free(buffer);
env->DeleteGlobalRef(globalRef);
}
然后我使用以下代码在JAVA端获取我的ByteBuffer:
ByteBuffer myBuf = allocNative(LARGE_NUMBER);
并使用free函数释放它。
freeNative(myBuf);
很不幸,虽然它可以正常分配内存,但是a)它仍然会保留已分配的内存大小,根据 Debug.getNativeHeapAllocatedSize()
,b)这还会导致错误。
W/dalvikvm(26733): JNI: DeleteGlobalRef(0x462b05a0) failed to find entry (valid=1)
我现在非常困惑,原以为自己至少理解了C++方面的事情…为什么free()没有返回内存?而且我在使用DeleteGlobalRef()
时做错了什么?
allocateDirect
方法分配的内存被保证不会被垃圾回收器重新定位。但一旦ByteBuffer
被回收,本地内存将被收回。 - Gregory PakoszNewGlobalRef
和DeleteGlobalRef
的编辑后的答案。 - Gregory Pakosz