Java 当返回在JNI中创建的对象时,NewGlobalRef/DeleteGlobalRef

Java 当返回在JNI中创建的对象时,NewGlobalRef/DeleteGlobalRef,java,android-ndk,java-native-interface,Java,Android Ndk,Java Native Interface,当将对JNI方法中创建的对象的引用返回给Java时,我们是否应该返回对已创建对象的NewGlobalRef调用的结果?稍后,当Java不再需要对象时,我们是否需要调用JNI方法对从Java传递的引用执行DeleteGlobalRef 或者NewGlobalRef/DeleteGlobalRef只需要在JNI方法调用之间保存对JNI内Java对象的引用,如果我们只是将创建的对象返回给Java,我们就不需要进行NewGlobalRef/DeleteGlobalRef调用 我在一个大型开源项目中看到过

当将对JNI方法中创建的对象的引用返回给Java时,我们是否应该返回对已创建对象的NewGlobalRef调用的结果?稍后,当Java不再需要对象时,我们是否需要调用JNI方法对从Java传递的引用执行DeleteGlobalRef

或者NewGlobalRef/DeleteGlobalRef只需要在JNI方法调用之间保存对JNI内Java对象的引用,如果我们只是将创建的对象返回给Java,我们就不需要进行NewGlobalRef/DeleteGlobalRef调用

我在一个大型开源项目中看到过这样的情况:

extern "C" JNIEXPORT jobject JNICALL
Java_foo_bar_Baz_create(JNIEnv* env, jclass, jint size) {
    void* buf = malloc(size);
    jobject obj = env->NewDirectByteBuffer(buf, size);
    return env->NewGlobalRef(obj);
}

extern "C" JNIEXPORT void JNICALL
Java_foo_bar_Baz_free(JNIEnv* env, jclass, jobject jbuffer) {
    void* buf = env->GetDirectBufferAddress(jbuffer);        
    free(buf);
}
它对创建的NewDirectByteBuffer对象返回NewGlobalRef调用的结果,之后,当Java中不再需要该对象时,会调用JNI方法,该方法不调用DeleteGlobalRef,只调用本机缓冲区地址上的free()

当将对
New[Type]数组、
或在JNI方法中创建的其他对象的引用返回给Java时,我们是否应该返回对已创建对象的
NewGlobalRef
调用的结果

仅当您还希望保留该引用以在将来的JNI调用中使用,而不将其作为JNI方法参数再次接收时

稍后,当Java不再需要object时,我们是否需要调用JNI方法对Java传递的引用执行
DeleteGlobalRef

仅当您对其调用了
NewGlobalRef()

或者
NewGlobalRef/DeleteGlobalRef
仅用于在JNI方法调用之间保存对JNI内部Java对象的引用

绝对正确

如果我们简单地将创建的对象返回给Java,我们就不需要执行
NewGlobalRef/DeleteGlobalRef
调用了

请再说一遍

我在大型开源项目中看到了创建的
NewDirectByteBuffer
对象(通过
malloc()
分配的真实缓冲区)上的
NewGlobalRef
的返回结果。后来,当Java中不再需要对象时,会调用JNI方法,该方法不会执行
DeleteGlobalRef,
,而只是对从
GetDirectBufferAddress获取的本机缓冲区地址调用
free()


这将构成
DirectByteBuffer
对象的泄漏,但不是其本机缓冲区的泄漏。

我刚刚回答了这个问题。@Dima我再次回答了这个问题。我不明白你为什么老是问我同样的问题。我也没说什么“实际决定”。