jni deleteRef用于jclass和jobject

时间:2016-12-06 10:39:09

标签: c++ java-native-interface

是删除jclass和jobject

的引用的正确方法
JNIEXPORT void JNICALL Java_method(JNIEnv *env,jobject, jobject objArray)
{
    int n = env->GetArrayLength(objArray);

    for (int i = 0; i<n ; ++i)
    {
        jobject sObject = env->GetObjectArrayElement(objArray, i);
        jclass sObjectClass = env->GetObjectClass(sObject);

        dosomething(sObjectClass, sObject);

        env->DeleteLocalRef(sObject);
        env->DeleteLocalRef(sObjectClass);
    }

1 个答案:

答案 0 :(得分:2)

简答:

是的,这是正确的方式。调用DeleteLocalRef不是必需的,但如果objArray很大或者函数执行时间很长,它就很有用。

更长的回答:

Oracle参考文档说明

  

复制原始类型,例如整数,字符等   Java和本机代码之间。另一方面是任意Java对象   手,通过参考传递。 VM必须跟踪所有对象   已传递给本机代码,以便这些对象   没有被垃圾收集器释放。反过来,本机代码必须   有办法通知VM它不再需要这些对象。在   此外,垃圾收集器必须能够移动对象   由本机代码引用。

因此,当本机代码确实需要该对象时,本机代码使用的任何对象都必须从本机代码的角度标记为有资格进行垃圾回收。 JNI有两种类型的引用 - 全局引用和本地引用。从GetObjectArrayElementGetObjectClass检索到的引用是本地的,因为:

  

JNI函数返回的所有Java对象都是本地引用。

VM在本机函数返回时自动释放所有本地引用。因此,在大多数情况下,没有必要通过DeleteLocalRef释放这些引用,因为VM会自动释放它们。

但是如果在一个函数调用中需要很多本地引用,或者调用需要很长时间,则在不需要它们时立即显式释放它们并且不等待函数返回是值得的。 Freeing可以帮助VM更好地进行内存管理。