我是否需要明确处理jbyteArray?

时间:2015-12-09 11:13:22

标签: java-native-interface

我正在编写一个函数,首先创建一个新的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“正确”,它将被简单地垃圾收集。这是对的吗?

1 个答案:

答案 0 :(得分:2)

如果这是通过Java本机方法调用的函数,那么运行时将为您处理jbyteArray本地引用。从文档:“本地引用在本机方法调用的持续时间内有效,并在本机方法返回后自动释放。”一旦释放了本地引用并且没有任何其他引用(将对象返回到Java创建新引用),该对象就有资格进行垃圾回收。

例外情况是,如果你有很多像这样的引用。 VM可以处理多少本地引用是有限制的,但是如果你保持低于该值,那么你就是好的。

如果在使用JNI_CreateJavaVM()创建VM的非Java进程中的函数中,则必须显式删除在Java本机方法调用之外创建的每个引用。在本机方法调用内部,VM会为您创建一个引用空间,以便在本机方法返回时进行销毁。当您通过envJNI_CreateJavaVM()AttachCurrentThread()获得GetEnv()指针时,VM将不会为您管理为env创建的引用。

还有一个编辑:看起来好像DetachCurrentThread()已被视为免费本地参考。我很确定,但是,我已经读过它没有的问题。也许它依赖于实现,也许报告的问题是由于一个bug。文档没有说明,所以我宁愿不依赖它。