我在native中创建并分配DirectByteBuffer。然后我将它传回Java。由于DirectByteBuffer是在C中分配的,因此它驻留在堆内存中并且免受"免疫"到Java的垃圾收集器,对吗?解放它的唯一方法是使用free()?
但是在JNI中缓冲对象上调用(* env) - > GetObjectRefType()会返回1,这意味着它是本地引用。当JNI方法返回时,Java的GC会自动释放本地引用。在这种情况下,有人可以澄清GC被释放的内容吗?我应该使用(* env) - > NewGlobalRef(env,bb)将分配的缓冲区转换为Global ref吗?
C:
JNIEXPORT jobject JNICALL Java_main_Main_byteBufferTest2(JNIEnv *env, jobject obj){
double *dp = malloc(sizeof(double)*100);
jobject bb = (*env)->NewDirectByteBuffer(env, (void*)dp, sizeof(double)*100);
return bb;
}
爪哇:
ByteBuffer dbb = byteBufferTest2();
答案 0 :(得分:0)
当JNI方法返回时,将释放本地引用。但是,如果您返回对Java代码的本地引用,那么Java代码现在可以引用它。当没有引用时,对象可以垃圾收集。这不是一回事。
由于DirectByteBuffer是在C中分配的,它驻留在堆内存中并且对Java的垃圾收集器“免疫”,对吗?
错误。
释放它的唯一方法是从C使用free()?
错误。它是一个Java对象,与任何其他Java对象一样受GC影响。如果您尝试free()
它将会崩溃。
但是在JNI中缓冲对象上调用(* env) - > GetObjectRefType()会返回1,这意味着它是本地引用。
正确。
当JNI方法返回时,Java的GC会自动释放本地引用。
没有。你正在混合对象和引用。该引用由JNI释放。当没有更多引用时,可以释放对象。
我应该使用(* env) - > NewGlobalRef(env,bb)将分配的缓冲区转换为全局参考吗?
除非你想在后续的JNI方法中再次使用它而不将其作为参数传递。