Android ICSとJNIのバグ管理強化
Android ndk(JNI)を使って、nativeのプログラムを作成(移植)するとき、一番、神経質に考えているのがメモリ管理である。 Ice cream sandwatchはメモリ管理のバグを発見する機能がディフォルトで追加されているようだ。
以下のblogに書いてある
http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html
詳細は上の記事に述べてあるが、項目を列挙すると。
A quick primer on JNI referencesからOld AndroidではJNIEnv*が単なるポインターであり、Delete系を呼んだあとでも使えてしまう。 そのため、バグが見つかりにくい欠点があるし、誤解を招く原因にもなる。
JNIはグローバルとローカルでJNIEnv*があり、スレッドがそれぞれ持っているが、グローバルは他のスレッドから利用可能だ。 AndroidではJNIEnv*は1スレッド専用であり、ほかのスレッドでは使えない。 ICSではそのバグを監視する機能がディフォルト(debug指定時)でONになっている。
例から
以下のblogに書いてある
http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html
詳細は上の記事に述べてあるが、項目を列挙すると。
A quick primer on JNI referencesからOld AndroidではJNIEnv*が単なるポインターであり、Delete系を呼んだあとでも使えてしまう。 そのため、バグが見つかりにくい欠点があるし、誤解を招く原因にもなる。
JNIはグローバルとローカルでJNIEnv*があり、スレッドがそれぞれ持っているが、グローバルは他のスレッドから利用可能だ。 AndroidではJNIEnv*は1スレッド専用であり、ほかのスレッドでは使えない。 ICSではそのバグを監視する機能がディフォルト(debug指定時)でONになっている。
例から
- env->NewStringUTFはローカルリファレンスを返すので、グローバルとしては使えない。
- env->NewGlobalRef(s)はグローバルとして使えるが、env->DeleteGlobalRef(s);を呼ぶことを忘れてはならない。
- FindClass() はローカルリファレンスを返す。グローバルとしては使えない。
DeleteLocalRef()
を使うべきではない。 呼んだあとでもAndroid場合使えてしまうのでバグが発見しづらい。- PopLocalFrame()以後のPushLocalFrame()で割り当てたリファレンスは使えない。
コメント
コメントを投稿