Recently I have been working on a JNI related project. Everything would have been fine, waiting for the release of the test, but the ideal is beautiful, the reality is skinny. The beta came to me and told me that there was a flashback problem while testing the abnormal flow (developers get headaches when they hear about it). Local Reference table overflow (Max =512) Huh? Memory leak in JNI? However, I have already released all the objects according to the example on the Internet. What happened?
Here’s what to release:
-
FindClass
jclass ref= (env)->FindClass("java/lang/String"); env->DeleteLocalRef(ref); Copy the code
-
NewString/ NewStringUTF/NewObject/NewByteArray
// Create jString and char* jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, test1, test2); char* cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0); / / release (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr); (*jniEnv)->DeleteLocalRef(jniEnv, jstr); Copy the code
-
GetObjectField/GetObjectClass/GetObjectArrayElement
jclass ref = env->GetObjectClass(robj); env->DeleteLocalRef(ref); Copy the code
-
GetByteArrayElements
jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy); (*env)->ReleaseByteArrayElements(env,jarray,array.0); Copy the code
-
NewGlobalRef/DeleteGlobalRef
jobject ref= env->NewGlobalRef(customObj); env->DeleteGlobalRef(customObj); Copy the code
Began the helpless and painful code inspection road, looking for a long time, considering all kinds of possible reasons, and then a variety of tests, or in the abnormal process flash back, desperate.
Finally, I saw this:
jbyteArray arr = (jbyteArray) (*env)->CallObjectMethod(env, local_object, methodID, java_slot,jbyteArray1);
Copy the code
Reflection calls the Java layer method from JNI and returns an array of bytes that I go to… Local Reference Table overflow (Max =512) error quickly occurs as the array is created in the exception flow and is not reclaimed. Find the root cause of the problem, quickly check the code, all similar interfaces are modified.
(*env)->DeleteLocalRef(env, arr);
Copy the code
And then we tested it again, and there was no problem.
It took me most of the afternoon to solve the one-line problem, so make a note here to remind myself that in the future, remember to release all Native objects created in the Native layer!