When returning reference to object created in JNI method to Java, should we return result of NewGlobalRef call on created object? And, respectively, later, when object no more required in Java, do we need to call JNI method to do DeleteGlobalRef on the reference passed from Java?
Or NewGlobalRef/DeleteGlobalRef required only to hold references to Java object inside JNI, between JNI methods calls, and if we simply return created object to Java we dont need to do NewGlobalRef/DeleteGlobalRef calls?
I've seen such thing in a large open source project:
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);
}
It return result of NewGlobalRef call on created NewDirectByteBuffer object, and later, when object no more required in Java, there is a call to JNI method that does not call DeleteGlobalRef, but just call free() on the native buffer address.
When returning reference to
New[Type]Array,
or other object created in JNI method to Java, should we return result ofNewGlobalRef
call on created object?
Only if you also want to retain that reference for use in future JNI calls without receiving it again as a JNI method parameter.
And respectively, later, when object no more required in Java, do we need to call JNI method to do
DeleteGlobalRef
on the reference passed from Java?
Only if you called NewGlobalRef()
on it.
Or
NewGlobalRef/DeleteGlobalRef
required only to hold references to Java object inside JNI, between JNI methods calls
Absolutely correct.
and if we simply return created object to Java we dont need to do
NewGlobalRef/DeleteGlobalRef
calls?
Correct again.
I saw returning result of
NewGlobalRef
on createdNewDirectByteBuffer
object (real buffer allocated viamalloc()
), in large open source project. And later, when object no more required in Java, there is a call to JNI method, that don't doDeleteGlobalRef,
but just callfree()
on the native buffer address obtained fromGetDirectBufferAddress.
That would constitute a leak of the DirectByteBuffer
object, but not of its native buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With