在jni中,我们有GetPrimitiveArrayElements
函数来获取指向堆上数组元素的指针,ReleasePrimitiveArrayElements
来删除数组的本地副本。
但是我将java对象的数组传递给JNI。这些数组元素使用GetObjectArrayElement
函数迭代到本地jobject。
但是如何在处理数组元素后删除jobject的本地引用。
由于
答案 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函数创建额外的本地引用,除了它们作为结果返回的引用。
本地引用仅在创建它们的线程中有效。本机代码不能将本地引用从一个线程传递到另一个线程。