牛骨文教育服务平台(让学习变的简单)
博文笔记

jni 遇到的坑--DeleteLocalRef仍然有local reference table overflow

创建时间:2018-01-15 投稿人: 浏览次数:254

在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类。这时,就可以定位到红色代码了

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。