即使在deleteLocalRef之后jni表溢出

she*_*vis 6 java-native-interface android reference overflow

当我运行代码时,我收到错误"添加到JNI本地ref表失败有512个条目"

这是我的代码:

jstring pJNIData = pJNIEnv->NewStringUTF ( variables[0].GetStringValue() );

pJNIEnv->CallStaticVoidMethod ( pJNIActivityClass, pJNIMethodIDStartTime, pJNIData ) ;

pJNIEnv->DeleteLocalRef(pJNIData);
Run Code Online (Sandbox Code Playgroud)

我已经阅读了几条建议,但没有一条能起作用!尽管如此DeleteLocalRef,它仍无法运作.该函数用于一个字面上调用所有函数的分析器......

184*_*615 2

当 JNI 方法调用 Java 代码时(在我的例子中,该方法不是静态的),我已经看到了这一点。据我了解,当从 JNI 调用 Java 方法时,未使用的本地引用不会自动删除(我的意思是,直到顶级 JNI 函数返回)。

IIRC 要么日志中已有有关内存对象的信息,要么我可以添加一些日志记录;根据这些信息,我确定了我之前没有提到的垃圾项目。它们是两个数组和一个类,在后续调用中创建,但不会被垃圾回收。

// in a function that calls a Java method from JNI
jbyteArray srcArray = env->NewByteArray(len);
jclass cls = env->FindClass("com/something/MyClass");
jmethodID mid = env->GetMethodID(cls, "mymethod", "([BI)[B");
jbyteArray resArray = (jbyteArray)env->CallObjectMethod(obj, mid, srcArray, XXXX);

...
env->DeleteLocalRef(cls);
env->DeleteLocalRef(resArray);
env->DeleteLocalRef(srcArray);
// no need to do anything with mid
Run Code Online (Sandbox Code Playgroud)

请注意,尽管这三个本地引用的获取方式不同,但它们都存在。

有用的链接: http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references (或找到 Dalvik VM 文档 dalvik/docs/jni-tips.html 并找到“本地”部分与全局参考”)

JNI 返回的每个对象都是“本地引用”。这意味着它在当前线程中的当前本机方法的持续时间内有效。即使对象本身在本机方法返回后继续存在,引用也是无效的。这适用于 jobject 的所有子类,包括 jclass 和 jarray。[...] 注意:方法和字段 ID 只是 32 位标识符,而不是对象引用,并且不应传递给 NewGlobalRef。GetStringUTFChars 和 GetByteArrayElements 等函数返回的原始数据指针也不是对象。