Today I needs record some experience about Java JNI programming,
More accuratly, it’s about the local reference in JNI.
first of all, about JNI’s reference , see this link for a basic knowlege: (http://www.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.win.80.doc/diag/understanding/jni_refs.html).
In this post, I’m going to talk about:
1) when JNI function will generate a local reference.
2) when the local reference will be release automatily by java vm.
3) what issue might happens about it.
1. When JNI function will generate a local reference.
Basic rule is simple:
1) the function not return a GlobalReference / WeakGlobalReferece
2) the function will return a point named in follwing list:
jobject, jclass, jstring, jarray, jobjectArray, jbooleanArray, jbyteArray, jcharArray, jshortArray,
jintArray, jlongArray;, floatArray, jdoubleArray, jthrowable, jweak.
actually , this list is copy from jni.h , there is a section named /* Reference types */
When these two rules apply, it will generate a LocalReference.
2. when the local reference will be release automatily by java vm.
In java document, said that the local Reference will be freeed after *native* call.
but what’s is the native call, let’s give a example.
A.java : have one native function:
native void method_native();
Jni.cpp: have 3 function:
JNIEXPORT void JNICALL Java_com_example_ClassA_A_method_native(JNIEnv *env, jobject thiz);
void cpp_function_1(JNIEnv *env, jobject thiz);
void cpp_function_2(JNIEnv *env, jobject thiz);
in cpp_function_2() you called env->GetObjectClass(this); to do something.
call relationship is:
method_native() -> cpp_function_1() -> cpp_function_2();
in cpp_function_2() it will generate a localReference, it will not release after cpp_function_2() return,
it will actually release after method_native() return.
or, if you have called vm_->DetachCurrentThread(); (vm_ is JavaVM type), the local reference will release too.
3. what issue might happens about it.
So, since java vm will release the reference , why bother to learn this ?
because in some case, you will leak the local reference, or exceed the maximum count of local reference, and cause you program crash.
like, you called GetObjectClass() function in a worker thread in native level, and this thread never return control to java level.
so it leaked.
if you have some loop calling a function will generate a local reference, it will generate local reference inside the loop, even if it will eventually release by jvm after native function return , it will have some chance exceed the maximum count of local reference.
So, as a summary , the good practice is release the local reference by DeleteLocalReference() as soon as possible.