GCで止まらないように

TheServerSide.COM - http://www.theserverside.com/ - の記事で、ガーベジコレクションについての記事が出てたので、読んでみた。ほぼ既知だけど、確かに意識しないと忘れちゃう内容かも。


自分なりにまとめてみると:

  • ガーベジコレクションの速さは、オブジェクトのサイズではなく、数に依存する。
  • 長い間生存するオブジェクトで影響を受ける(これは、最近のJavaGCアルゴリズムを見ると確認できるけど、短期の生存オブジェクトと、長期の生存オブジェクトみたいな風に分けられる。その中の、ずーっと生き残るオブジェクトの方。メソッドのローカル変数じゃなくて、メンバとか、その他のオブジェクトの方って考えるのが比較的わかりやすいかも)。
  • これらのオブジェクトを開放するときに、全てのスレッドがスキャンされるので、気をつける。
  • Performanceの分析をして、IntegerとかBooleanのようなオブジェクトが上位に来るようであれば、new Integer() や new Boolean() ではなく、Integer.valueOf()、 Boolean.valueOf() を利用するようにする。Boolean であれば、Boolean.TRUE または Boolean.FALSE という予め定義されたオブジェクトを返すことで、オブジェクトの数を最小化できる。 Integer.valueOf(int) とかを使うと、JDK1.5 からは、内部的なキャッシュを保持する(byteの範囲だけど)ので、これも有効になるという事だろう。(JDK付属のsrc.zipを展開してみてみればわかる)。これは、Longとかも同じだ。
  • 何かのオブジェクトを管理する場合に、闇雲に HashMap みたいなのを使っちゃうと、単独のクラスを作成するよりも、オブジェクト数が増える場合があるので、必要な場合は、クラスを作成するか Map の実装を検討する。例えば、クラスのメンバが4つあって、1つがStringで他が、int のような場合、普通にクラスを作れば、クラス自身とメンバのStringの2つのオブジェクトで済む。でも、Mapで、4つのメンバを管理すると、MapEntryや、その値のそれぞれにオブジェクトが必要になって、何倍にもオブジェクトの数が膨らむという感じだ。

参考:
TheServerSide.COM の記事 : http://www.theserverside.com/news/thread.tss?thread_id=36832
Object Count Impact on Garbage Collection Performance: http://jroller.com/page/slobodan?entry=object_count_impact_on_garbage