JNI层开发会遇到ReferenceTable overflow问题,特别是当jni函数被反复调用上千上万次的时候,现汇总如下
对于FindClass 返回的一定需要调用DeleteLocalRef,还有如下类型的变量需要DeleteLocalRef:
.FindClass /NewString/ NewStringUTF/NewObject/ GetObjectField等产生的都是LocalRef
总体原则:释放所有对object的引用。
1.FindClass
jclass ref= (env)->FindClass("java/lang/String"); env->DeleteLocalRef(ref);
2.NewString/ NewStringUTF/NewObject/NewByteArray
jstring (*NewString)(JNIEnv*, const jchar*, jsize); const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
jstring (*NewStringUTF)(JNIEnv*, const char*); const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
env->DeleteLocalRef(ref);
3.GetObjectField/GetObjectClass/GetObjectArrayElement
jclass ref = env->GetObjectClass(robj); env->DeleteLocalRef(ref);
4.GetByteArrayElements
jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy); (*env)->ReleaseByteArrayElements(env,jarray,array,0);
5.const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy);
(*env)->ReleaseStringUTFChars(env,jinput,input);
6.NewGlobalRef/DeleteGlobalRef
jobject (*NewGlobalRef)(JNIEnv*, jobject); void (*DeleteGlobalRef)(JNIEnv*, jobject);
例如,
jobject ref= env->NewGlobalRef(customObj); env->DeleteGlobalRef(customObj);