当我将直接的ByteBuffer返回给JNI时,JVM / GC可以回收多长时间?
假设我有这样的功能:
void* func()
{
[ ... ]
jobject result = env->CallStaticObjectMethod(testClass, doSomethingMethod);
void* pointerToMemory = env->GetDirectBufferAddress(result);
return pointerToMemory;
}
JVM可能不知道我将使用pointerToMemory
多长时间,对吗?如果我想暂时保留该地址和相应的内存会怎么样?
假设我想绕过这个问题并将一个byte []从Java返回到JNI,如下所示:
ByteBuffer buf;
byte[] b = new byte[1000];
buf = ByteBuffer.wrap(b);
buf.order(ByteOrder.BIG_ENDIAN);
return buf.array();
然后执行与上面相同的操作,我存储了一个指向该字节[]的指针,并希望保持一段时间。如何/何时/为什么JVM将来自Java的后备字节[]?
void* function()
{
jbyteArray byteArr = (jbytearray)env->CallStaticObjectMethod(testClass, doSomethingMethod);
jbyte *b= env->GetByteArrayElements(byteArr, 0);
return b;
}
答案 0 :(得分:1)
简短的回答是:如果函数实现了本机方法,则返回后指针将无效。
为了避免这种情况,您应该获得在返回后打算保持有效的所有对象的全局引用。有关详细信息,请参阅local and global references上的文档。
要更好地了解JNI如何管理本机代码的引用,请参阅documentation on PushLocalFrame/PopLocalFrame。