我看到这个时,一个JNI方法调用Java代码(在我的情况下,该方法不是静态的)。据我所知,当从JNI(我的意思是,直到顶层JNI函数返回)调用Java方法时,未使用的本地引用是而不是自动删除。
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
请注意,尽管这三个地方的参考文献是以不同的方式获得的,但所有这些参考文献都是悬而未决的。
有用的链接: http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references (或找到Dalvik虚拟机Dalvik的文档/文件/ JNI的tips.html请与下方找到“本地与全球参考”)
每个对象JNI返回是“本地参考”。这意味着它在当前线程中当前本地方法的有效期内有效。即使在本地方法返回后对象本身继续活动,引用也是无效的。这适用于jobject的所有子类,包括jclass和jarray。 [...]注意:方法和字段ID只是32位标识符,不是对象引用,不应传递给NewGlobalRef。像GetStringUTFChars和GetByteArrayElements这样的函数返回的原始数据指针也不是对象。
你确定这是代码填满你的ref表吗?当你使用一个常量硬编码的pJNIData时问题会消失吗? –
@vtmarvin不确定。这是否对参考表有所不同? - > JNIEnv * pJNIEnv = profilerGetJNIEnv(); 如果(pJNIEnv!) \t \t { \t \t \t LOGE( “探查ERROR:Java环境缺失(空)”); \t \t \t return; \t \t} –