About Java Native Programming(JNI) Local Reference

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.