我看到這個時,一個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} –