ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

JNIローカル参照

2006-11-09 22:21:05 | PG(Java)

JNIで、例外が起きたかどうかのみをチェックできる関数があった。
今までExceptionOccurred()を使ってたんだけど、これが返すオブジェクト(例外インスタンス)は、実はローカル参照を保持しているらしい。
つまり関数実行中はJNIのJavaVMは「使用中」と判断するわけ。
この判断情報を保持する領域も限られているから、どんどんExceptionOccurred()を使うと、無駄にリソースが使われてしまうということ。

で、普通のJavaのソースならローカル変数にnullを入れることによってローカル参照を終了させていたけど、C言語/C++ではローカル変数にNULLを代入したところで、JavaVMに分かるはずがない。
ちゅーわけで、DeleteLocalRef()という関数を呼ぶと ローカル参照を終了できるらしい。
まぁこれを呼ばなくても、JNIの呼び出しが終了すればローカル参照は全部解放してくれるらしいので、すぐ終わる関数ならそんなに気にする必要は無いでしょう。


ちなみに何故こんなことを調べていたかというと、自作のJNI関数がメモリリークしてたみたいだったので、オブジェクトがどう解放されるかを知りたかったから。
結果的にはローカル参照は関係なくて、Releaseの仕方が間違ってたんだけど。
↓要点だけ抜き出すと こんな感じ

 jbyte* elems = env->GetByteArrayElements(arrj, NULL);
 elems += 128;
 env->ReleaseByteArrayElements(arrj, elems, JNI_ABORT);

これに気付いたときには、我ながら唖然としたね(呆)
取得したポインターをずらして、それを解放できるわけないじゃん!!!
解放動作がJNI_ABORTだったのでたまたま例外が発生したりはしなかったみたいだけど、当然メモリの解放は正常に行われず、正にメモリリークしていたわけ。
“昔の自分”ってヤツぁ、馬鹿だね(嘆)


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Javaのメモリ使用量 | トップ | パケットキャプチャー→ラダー... »
最新の画像もっと見る

コメントを投稿

PG(Java)」カテゴリの最新記事