在
Android上,一个直接的ByteBuffer似乎并没有释放它的内存,甚至在调用System.gc()时也是如此.
例如:做
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);
并释放它
freeNative(myBuf);
不幸的是,虽然它分配的很好,它a)仍然保留根据Debug.getNativeHeapAllocatedSize()分配的内存和b)导致错误
W/dalvikvm(26733): JNI: DeleteGlobalRef(0x462b05a0) Failed to find entry (valid=1)
我现在彻底迷惑了,我以为我至少明白了C方面的事情…为什么是free()没有返回内存?我在DeleteGlobalRef()中做错了什么?