在jni中忘记写DeleteLocalRef 导致JNI ERROR (app bug): local reference table overflow (max=512)是经常容易犯的错误。
今天这个错误又非常隐蔽:
jni错误用例:
jstring jScene = StringFromStdString(env,(char const*) cScene);
jclass jMsgTypeClass = WGPlatform::GetClass("com/tencent/msdk/notice/eMSG_NOTICETYPE",env);
jmethodID jGetMsgTypeValueMethod = env->GetMethodID(jMsgTypeClass, "val","()I");
jclass jContentTypeClass = WGPlatform::GetClass("com/tencent/msdk/notice/eMSG_CONTENTTYPE",env);
jmethodID jGetContentTypeEnumMethod = env->GetStaticMethodID(jContentTypeClass, "getEnum",
"(I)Lcom/tencent/msdk/notice/eMSG_CONTENTTYPE;");
jmethodID jGetContentTypeValueMethod = env->GetMethodID(jContentTypeClass, "val","()I");
jclass jPicScreenDirClass = WGPlatform::GetClass("com/tencent/msdk/notice/eMSDK_SCREENDIR",env);
jmethodID jGetPicScreenDirEnumMethod = env->GetStaticMethodID(jPicScreenDirClass, "getEnum",
"(I)Lcom/tencent/msdk/notice/eMSDK_SCREENDIR;");
jmethodID jGetPicScreenDirValueMethod = env->GetMethodID(jPicScreenDirClass, "val","()I");
jclass jVectorClass = WGPlatform::GetClass("java/util/Vector",env);
jmethodID jVectorInitMethod = env->GetMethodID(jVectorClass, "<init>", "()V");
jmethodID jVectorSizeMethod = env->GetMethodID(jVectorClass, "size", "()I");
jmethodID jVectorGetMethod = env->GetMethodID(jVectorClass, "get", "(I)Ljava/lang/Object;");
jobject jNoticeVectorObj = env->NewObject(jVectorClass, jVectorInitMethod);
jobject jNoticeVectorObj = env->CallStaticObjectMethod(s_WGPlatformClass,jWGGetNoticeMethod,jScene);
env->DeleteLocalRef(jNoticeVectorObj);
通过打印引用表+代码排查,才发现问题
打印jni引用表方法:
static void printDumpReferenceTables(JNIEnv *env) {
jclass vm_class = WGPlatform::GetInstance()->GetClass("dalvik/system/VMDebug", env);
jmethodID dump_mid = env->GetStaticMethodID(vm_class, "dumpReferenceTables", "()V");
env->CallStaticVoidMethod(vm_class, dump_mid);
env->DeleteLocalRef(vm_class);
发现每次都多个vector,而第一次vector出现的地方,ni引用表中的位置大致相同。就是jni引用表出现了eMSDK_SCREENDIR类之后,就出现了vector类。这时,就可以定位到红色代码了