2011年5月6日金曜日

SoftReferenceに関して調べてみた。

xmlsocketのサーバーアプリでメモリー上にデータを残すために、属性を実装しようと思う。
基本的にMapにデータをいれておくわけだが、普通にHashMapとかにしておくと、そのうちOut of Memoryが発生してプログラムがこわれてしまう。
そこでReferenceを使おうと思うのですが、WeakHashMapだとGCがあるたびにデータが消し飛びます。
そこで目をつけたのがSoftReferenceの実装
というわけでメモリーの仕様状況をさっくり調べてみた。
まず普通のHashMapの場合 Map<Object, Object>
こんな感じで120Mまで使い切ってしまいました。
ためるだけためてout of memoryの例外がでて、それまで。
xmlsocketのPHP実装でつくっていたので、イベントでさらにデータのセットを行うタイマー処理をサイドまわしたら即out of memoryが再発。あたりまえですね。もうメモリーの残量はないのでうごくわけない。

続いてSoftHashMapをいれた場合 Map<Object, SoftReference<Object>>
120M近くまであがったらメモリーが解放されているのがわかります。
ただし、かならず120M近くまであがったら解放されるわけではないことがわかります。
また、一定のオブジェクトのみ参照を繰り返した場合(connect.phpで接続あるたびに一番はじめに設置した属性データを参照するようにしてました。)そのオブジェクトはいつまでたっても削除されませんでした。
どうやら頻度の多いデータは優先的にのこるようになっているようです。
また、connect.phpを途中で書き換えてとなりのマップデータを参照してみたところnullになっていました。
さらにキーの数は初期化されずにどんどん増えていきました。

というわけで
・SoftReferenceはメモリーの使用量が多くなってきたら自動で解放される。
・アクセスの少ないデータが優先で消える、それから古いデータが優先で消える。
・Out of Memoryエラーが出る前に消える
・Map<Object, SoftReference<Object>>だとキーの方のデータがたまることでOut of Memoryエラーになりかねない。
ということがわかりました。

属性のプログラムの基本方針はSoftReferenceでよさそうですね。

0 件のコメント:

コメントを投稿