C++调用Java时,JNI局部引用的生命周期是多久?

3
当Java通过JNI调用C函数时,我们知道任何对类或对象的本地引用在C函数返回到Java后可能会失效。
然而,当只有C调用Java时,并不存在“返回到Java”的情况。因此,我不清楚这些引用何时会失效。
例如,下面的代码是错误的,因为aClass和anObject可能在调用完成后失效。
jclass aClass;
jobject anObject;

JNIEXPORT void JNICALL Java_example_method1(JNIEnv *env) {
    aClass = env->FindClass("AClass");
}

JNIEXPORT void JNICALL Java_example_method2(JNIEnv * env) {
    jmethodID constructor = env->GetMethodID( aClass, "<init>", "()V");
    anObject = env->NewObject(klass, constructor );
}

然而在下面的例子中,是什么导致了 aClassanObject 变得无效?只有对 DeleteLocalRef 的显式调用才会导致吗?

jclass aClass;
jobject anObject;

int main() {
        JavaVMInitArgs vm_args;
        JavaVMOption options[1];
        vm_args.version = JNI_VERSION_1_6;
        vm_args.nOptions = 1;
        options[0].optionString = "-Djava.class.path=.";
        vm_args.options = options;
        vm_args.ignoreUnrecognized = JNI_FALSE;
        JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);

        aClass = env->FindClass("AClass");
        jmethodID constructor = env->GetMethodID( aClass, "<init>", "()V");
        anObject = env->NewObject(klass, constructor );
}
2个回答

1

是的。当Java调用JNI时,它会分配一个表格来存储本地引用,并在JNI返回时释放所有引用。但是,当您调用Java时,没有这样的机制。


1
在Java调用中使用PushLocalFrame/PopLocalFrame对括号进行分组是一个好主意,它会自动清理生成的任何引用。 - technomage
我认为这是正确的,但你知道有什么参考资料可以支持吗? - Michael Anderson
@MichaelAnderson 不确定你在这里寻找什么。第一部分在JNI规范,全局和本地引用:实现本地引用中已经说明,但你已经知道了。第二部分显然是显而易见的。 - user207421

0
本地引用在本地方法调用期间有效,并在本地方法返回后自动释放。全局引用保持有效,直到它们被显式释放。
本地引用仅在创建它们的线程中有效。 来源

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接