jni-释放对象数组

时间:2011-04-14 05:26:34

标签: java java-native-interface

在jni中,我们有GetPrimitiveArrayElements函数来获取指向堆上数组元素的指针,ReleasePrimitiveArrayElements来删除数组的本地副本。

但是我将java对象的数组传递给JNI。这些数组元素使用GetObjectArrayElement函数迭代到本地jobject。

但是如何在处理数组元素后删除jobject的本地引用。

由于

2 个答案:

答案 0 :(得分:2)

无论您抓取的jobject最初是在Java端还是通过JNI方法分配,they will be handled by garbage collection,只要没有对象的延迟引用。因此,如果对jobject的本地引用只是局部变量,它们将在函数末尾消失,并且您的对象将有资格在正常事件原因中进行垃圾回收。如果对对象保留GlobalRef,则该对象仍然存在,并且本地引用将像任何未分配堆空间的局部变量一样消失。如果保留WeakRef,则可能会对对象进行垃圾回收,但如果没有,则对另一个JNI调用仍然有效。在JNI调用中保留对jobject的普通本地引用无效。

此外,如果您想立即释放本地参考而不是等待(例如,如果您在单个函数中创建了大量jobject个引用,请使用JNIEnv的DeleteLocalRef(env, jobj);方法。

无论如何,如果我犯了任何错误,the documentation应该告诉你需要知道的一切。

答案 1 :(得分:1)

您可以不做任何事情或致电DeleteLocalRef()

来自JNI Specification Chapter 2

  

全球和本地参考资料

     

JNI将本机代码使用的对象引用分为两类:本地引用和全局引用。本地引用在本机方法调用的持续时间内有效,并在本机方法返回后自动释放。全局引用在显式释放之前仍然有效。

     

将对象作为本地引用传递给本机方法。 JNI函数返回的所有Java对象都是本地引用。 JNI允许程序员从本地引用创建全局引用。期望Java对象接受全局和本地引用的JNI函数。本机方法可以返回对VM的本地或全局引用。

     

在大多数情况下,程序员应该依赖VM在本机方法返回后释放所有本地引用。但是,有时程序员应该明确地释放本地引用。例如,考虑以下情况:

     

本机方法访问大型Java对象,从而创建对Java对象的本地引用。然后,本机方法在返回调用方之前执行其他计算。对大型Java对象的本地引用将阻止对象被垃圾回收,即使该对象在计算的其余部分中不再使用。   本机方法会创建大量本地引用,但并非所有引用都同时使用。由于VM需要一定的空间来跟踪本地引用,因此创建太多本地引用可能会导致系统内存不足。例如,本机方法循环遍历大量对象,将元素作为本地引用检索,并在每次迭代时对一个元素进行操作。在每次迭代之后,程序员不再需要对数组元素的本地引用。

     

JNI允许程序员在本机方法中的任何位置手动删除本地引用。为了确保程序员可以手动释放本地引用,不允许JNI函数创建额外的本地引用,除了它们作为结果返回的引用。

     

本地引用仅在创建它们的线程中有效。本机代码不能将本地引用从一个线程传递到另一个线程。