これは、JNIメソッドがJavaコードと呼ばれるときに見たものです(私の場合、メソッドは静的ではありませんでした)。私が理解しているように、未使用のローカル参照は、JavaメソッドがJNIから呼び出されたときに(つまり、最上位のJNI関数が戻るまで)自動的に削除されません。
IIRCは、ログにメモリオブジェクトに関する情報がすでに存在するか、ログを追加することができます。その情報から、以前は触れなかったゴミを特定しました。それらは2つの配列と1つのクラスであり、後続の呼び出しで作成されましたが、ガベージコレクションは行われませんでした。
// 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
これらの3つのローカル参照は異なる方法で取得されましたが、すべてがぶらぶらしていたことに注意してください。
便利なリンク:
http: //www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references
(または、DalvikVMドキュメントdalvik/ docs / jni-tips.htmlを見つけて、「ローカル」セクションを見つけます。 vs.グローバルリファレンス")
JNIが返すすべてのオブジェクトは、「ローカル参照」です。これは、現在のスレッドの現在のネイティブメソッドの期間中有効であることを意味します。ネイティブメソッドが戻った後もオブジェクト自体が存続している場合でも、参照は無効です。これは、jclassやjarrayを含むjobjectのすべてのサブクラスに適用されます。[...]注:メソッドIDとフィールドIDは単なる32ビット識別子であり、オブジェクト参照ではないため、NewGlobalRefに渡さないでください。GetStringUTFCharsやGetByteArrayElementsなどの関数によって返される生データポインタもオブジェクトではありません。