メモリ消費

BluntIRCはうちでは起動しただけで26MB、一晩ほおっておくと65MB程度のメモリ使用量になります。 Java VMやSwingのことがあるから起動直後の26MBは仕方ないとしても、その後の膨れ方が尋常じゃありません。 なんでこんなに重いのか?

Javaのオブジェクト単位のメモリ管理

以下はsunのjavaでRuntime.freeMemory()を使って調べた値です。

メンバを全く持たないオブジェクトは8バイトのメモリを消費します。 おそらく(クラスIDまたは仮想関数テーブル)と(参照カウントまたはgc用のmark) が4バイトずつ確保されてしまうのでしょう。

要素数0のchar配列は16バイトのメモリを消費します。 先の空のオブジェクトの場合に加えて、配列の要素数と何かを持っているのだと思います。 この何かについてはよくわかりません。 char[]の場合、要素数を2にしてテストしてもメモリ消費は16バイトのままで、 要素数を3にするとメモリ消費は24になります。やっぱりよくわかりません。 ついでにオブジェクトの配列の場合、要素数1までは16バイトのままで、要素数2と3が24、要素数4が32バイトのメモリ消費になります。

長さ0のStringは40バイトのメモリを消費します。 Stringの中にあるメンバはchar[]への参照、int offset,count,hash で16バイト、 char[] が16バイト、 String自身の(クラスIDまたは仮想関数テーブル)と(参照カウントまたはgc用のmark)が8バイト、 あわせて40バイト…という計算になりますね。ナゾはありません。

CやC++の場合、継承などが不要な場合はメモリ管理を意識することで これらのコストをおさえることができます。 javaではオブジェクトはつねに参照を通して扱うし実行時型情報も常にもっているので、 普通にやると上記のコストは無視できません。

あらかじめ大きいbyte配列を確保して自前ヒープを用意する手もありますが、 かなりアレな気がするのでそこまではしていません。


で、手で計算してみるとバックスクロール1行につきおよそ500バイト…ちと多すぎ…。 30バッファ×2500行でおよそ36MBになってしまいます。

というのも余計なメモリ消費の原因になっているっぽいです。