我正在编写一个函数,首先创建一个新的jbyteArray
,如果其他所有工作,它将返回。如果函数中的其他所有内容都不成功,则会返回NULL。
但是如果在 之后的某个地方出现错误,我已成功调用NewByteArray()
,所以我需要在返回之前显式处理jbyteArray,或者我可以简单地把它留给垃圾收集器吗?
粗略的代码草图:
jbyteArray makeAndFill( JNIEnv *env )
{
jbyteArray ba = NULL ;
ba = (*env)->NewByteArray( env, 1000 ) ;
if( ba == NULL )
return NULL ;
/* so far so good /
if( fillme( ba ) )
{
/* Whoops, a problem ...
*
* DO I need to free the jbyteArray explicitly before
* returning NULL ?
*/
return NULL ;
}
/* everything was fine
*/
return ba ;
}
您可以假设fillme()执行所有必需的Get和Release代码,如果soem某些原因它有问题,则返回FALSE。如果fillme()无法正常工作,我们只希望函数返回NULL。
我的理解是,如果我不将JbyteArray从JNI返回到JAVA“正确”,它将被简单地垃圾收集。这是对的吗?
答案 0 :(得分:2)
如果这是通过Java本机方法调用的函数,那么运行时将为您处理jbyteArray
本地引用。从文档:“本地引用在本机方法调用的持续时间内有效,并在本机方法返回后自动释放。”一旦释放了本地引用并且没有任何其他引用(将对象返回到Java创建新引用),该对象就有资格进行垃圾回收。
例外情况是,如果你有很多像这样的引用。 VM可以处理多少本地引用是有限制的,但是如果你保持低于该值,那么你就是好的。
如果在使用JNI_CreateJavaVM()
创建VM的非Java进程中的函数中,则必须显式删除在Java本机方法调用之外创建的每个引用。在本机方法调用内部,VM会为您创建一个引用空间,以便在本机方法返回时进行销毁。当您通过env
或JNI_CreateJavaVM()
或AttachCurrentThread()
获得GetEnv()
指针时,VM将不会为您管理为env
创建的引用。
还有一个编辑:看起来好像DetachCurrentThread()
已被视为免费本地参考。我很确定,但是,我已经读过它没有的问题。也许它依赖于实现,也许报告的问题是由于一个bug。文档没有说明,所以我宁愿不依赖它。