即使JNI表溢出deleteLocalRefJNI、deleteLocalRef

2023-09-07 11:24:53 作者:思念゛泛滥成灾

当我运行code,我得到一个错误无法增加JNI本地参考表中有512项

When I run the code, I get an error "failed adding to JNI local ref table has 512 entries"

这是我的code:

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

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

pJNIEnv->DeleteLocalRef(pJNIData);

我已看过一些建议,但他们没有工作!尽管在 DeleteLocalRef ,它无法工作。该功能用于在一个分析器,从字面上调用所有功能...

I have read several suggestions, but none of them work! In spite of the DeleteLocalRef, it fails to works. The function is used in a profiler that literally calls all the functions...

推荐答案

我已经看到了这时候JNI方法称为Java code(在我的情况,该方法是不是静态的)。据我了解,未使用的本地引用的的没有的当Java方法是从JNI叫(我的意思是,直到顶级JNI函数返回)自动删除。

I have seen this when a JNI method called Java code (in my case, the method was not static). As I understand, unused local references are not automatically deleted when a Java method is called from JNI (I mean, until the top-level JNI function returns).

IIRC要么已经有了另外有关日志内存中的对象的信息,我也可以添加一些日志记录;从这些信息,我挑选,我没提到前的垃圾物品。他们是两个数组和一类,在随后的电话,但在不作为垃圾回收。

IIRC either there already was information about memory objects in the log, or I could add some logging; from that information I identified garbage items that I did not mention before. They were two arrays and a class, created in subsequent calls but not garbage-collected.

// 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

请注意,尽管这三个地方分别引用不同,得到,所有的人都徘徊。

Note that although these three local references were obtained differently, all of them were hanging around.

有用的链接: 的http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references (或找到Dalvik虚拟机Dalvik的文档/文档/ JNI-tips.html并找到一节本地与全球参考)

Useful link: http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references (or find the Dalvik VM docs dalvik/docs/jni-tips.html and locate the section "Local vs. Global References")

的每个对象JNI返回的是一个本地引用。这意味着,它是有效的在当前线程的当前本地方法的持续时间。即使对象本身延续了本地方法返回后住上,引用无效。这适用于所有子类jobject,包括JCLASS和jarray。 [...]注意:方法和字段ID只是32位标识符,而不是对象的引用,而不应被传递给NewGlobalRef。由像GetStringUTFChars和GetByteArrayElements函数返回原始数据的指针,也没有对象。的