- - PR -
JNI利用時のメモリ開放について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-06-15 17:22
はじめて投稿させていただきます。
現在、JavaのプラグラムからJNIを利用してCのライブラリを呼んでいます。 そこで、メモリ使用量をチェックしたところ、Javaのプログラムを実行させている プロセスが終了するまで、Cライブラリで利用したメモリが開放されていないようなのですが、 JNIを利用した場合の挙動は必ずそうなるのでしょうか? もしそのような挙動であれば、Webアプリとして利用した場合はメモリが開放されない ままなのでしょうか? それとも、いつかGCで開放されるのでしょうか? どなたかご教授ください、よろしくお願いします。 | ||||||||
|
投稿日時: 2006-06-15 19:11
「メモリが開放されていない」というのはどうやって検証したのでしょうか。 OSが書いてないんであれですが、ふつー、JNIだとmalloc()系を使います。 だから、C言語で書いたプログラムと挙動は一緒です。
「OS」の(NOT VM)GCなのが違うだけで、ちゃんと開放しておけばいつかOSが使用します。 | ||||||||
|
投稿日時: 2006-06-15 19:26
回答していただき、ありがとうございました。
また、不十分な情報で投稿してしまい、申し訳ありませんでした。 検証したOSはRedHat Linuxです。 メモリの使用状況は、vmstatコマンドで監視しています。 具体的には、JavaのプログラムからJNIクラスを連続で呼び出した後、 さらにJavaのプログラムでループを回してメモリの使用状況を確認ています。 JNIクラスを連続で呼び出しているときは、継続的に空きメモリが減少していき、 JNIクラスでの処理が終了したその後のループ処理の際に空きメモリは減少した ままとなって、Javaプログラムのプロセスが終了すれば空きメモリ量が回復します。 この検証方法では正確なメモリの挙動を把握できないでしょうか? | ||||||||
|
投稿日時: 2006-06-15 20:28
ぶっちゃけ、純粋なJavaプログラムの、ヒープメモリ使用量がvmstatからは監視
できない(RutimeクラスのfreeMemory(),totalMemory()を使わないとわからない) のと同じ問題だと思います。 ですので解決案は、 Cのライブラリ側にJavaのRuntime#freeMemory()やtotalMemory()と同様の機能を 見つけ、それを使うことだと思います。 もしそういう機能があるとしたら、GNU C Libraryの Virtual Memory Allocation And Paging あたりに載っているかと思います。 (私はこれらのページを読んでませんが) ---- 以下の事柄は確認を取ってませんので、事実と異なる部分があるかと思います。 Cのmallocなどのメモリ確保処理はlibc(glibc)経由でOSのシステムコールを呼び出し ます。(この動作は、Linuxであれば、ライブラリの呼び出しを監視するltrace、 システムコールの呼び出しを監視するstraceで確認できます。) ただし、OSのシステムコールの呼び出しは(プログラム内の関数呼び出しより) コストが高いこと、メモリ管理のオーバーヘッド(使用領域、空き領域の管理にも メモリを使います)を抑えることから、mallocは毎回システムコールを呼び出す わけではありません。 (また、システムコールはたぶんページ単位(4kbyte?)のメモリしか確保できない のではないかと思います。) mallocは手元のメモリプールからメモリを確保します。 メモリプールから確保できなかったときはシステムコールでメモリを多めに確保し、 その一部をmallocで返します。 残りのメモリはメモリプールに保持し、以後にmallocが呼ばれたときに使います。 また、freeのメモリ解放処理も同様です。freeで解放したメモリはOSに返される わけではなく、メモリプールに戻します。このメモリは再度mallocが呼び出さ れたときに使用されます。 よって、freeを行っても、メモリはOS自体には返されていないので、vmstatやps、 topが表示する「プロセスがOSから確保したメモリ(VSZ)」や「物理メモリ上に 置かれているメモリ量(RSS)」には反映されません。 もっとも、malloc/freeの実装によっては、ある程度OSにメモリを返すような処理も 可能かもしれませんし、malloc/freeを使わずにOSから直接メモリを得て自前で malloc/freeに当たる処理を行うことも可能です。その場合はvmstatなどにも反映 されると思います。 (省メモリな処理を行うパターンの1つだと思います。 書籍なら 省メモリプログラミング―メモリ制限のあるシステムのためのソフトウェアパターン集とか。 自分もかって高速化のために同様の処理を組んだことがありますし、C++のnewの 配置構文などはそういう用途も想定しているようです) [修正: GNU C Libraryのマニュアルのリンク先を変更] [ メッセージ編集済み 編集者: ちいにぃ 編集日時 2006-06-15 22:28 ] | ||||||||
|
投稿日時: 2006-06-15 21:19
ご回答ありがとうございました。
vmstatで調べていたこと自体が間違いだったとは・・・ 目からうろこです。 確かに、メモリがOSに返されていないのであれば、vmstatで調べると メモリが開放されないように見えますね。 >Cのライブラリ側にJavaのRuntime#freeMemory()やtotalMemory()と同様の機能を >見つけ、それを使うことだと思います。 > >もしそういう機能があるとしたら、GNU C Libraryの >Virtual Memory Allocation And Paging あたりに載っているかと思います。 参考にさせていただきます。 また、vmstatの情報や、ネイティブライブラリも調べ直してみたいと思います。 大変助かりました、どうもありがとうございました。 | ||||||||
|
投稿日時: 2006-11-06 00:16
2006年11月11日 発売予定の
Binary Hacks と 『Binary Hacks』サンプルPDF(+Extra Hacks) が 参考になるかも。 | ||||||||
|
投稿日時: 2006-11-15 00:37
ちょっと本題から外れますが、
YLUG 第67回カーネル読書会 - glibc malloc について の資料も面白いかも知れません。 - 第67回カーネル読書会 - カーネル読書会で講演してきました - 第67回カーネル読書会、ビデオ公開 | ||||||||
|
投稿日時: 2006-11-15 01:47
そもそもmalloc(3)ですから。システムコールではありません。 「OS」からメモリを取得するなら「システムコール」(2)なはずです。 最近は区別できないかな。。。 重要なことはそんなことではなく、システムに必要な「物理的メモリ量」 を測定することになると思います。 要するにシステム用に買う「パソコン」に「メモリ」はいくら買えばいいのか。 1GBでOK?2GB買うの?それとも16GB? という話なのでは。 JNIだと実測すると、もはやさっぱり分からないというのが実情だと思います。 だからJNIを使う気になれないかと。 Webアプリケーションなんて、コンテナがメモリを持ってる 実装のアプリケーションサーバがあるのでvmstatでは、全く分からないです。 だからWebアプリケーションサーバを販売している理由があるわけですから。 #だてに売ってるわけではないことが分からない顧客が居るのかもしれませんが。。 |