Effective Javaを読むチャレンジ-項目6-

項目6 廃れたオブジェクト参照を取り除く

非常に厄介なメモリリークの話。

Stackから取り出された配列の要素はガベージコレクトの対象外、だからnullで廃れた参照を取り除いてるわけですね。

実際にjava.util.StackのpopメソッドはremoveElementAtメソッド(実際は上位のVectorクラス)を用いて廃れた参照を取り除いてます。

この廃れた参照をnullで取り除くことをコーディング規約にしている現場がありましたが、その書きっぷりは「とにかく使い終わってもう参照されないオブジェクトにはnullを代入しておけ」という感じの実に大きな勘違いを誘うものでした。

これで何が起きたかというと、 「= null;」がコードのあちこちに蔓延することになりました。しかも本書の例のような場合には目もくれず、スコープの最後でローカル変数全部にnull入れるだけ。あと一歩でゴールというところで荷物を捨てて身軽にするようなものですね。荷物捨てるならもっと前に捨てるタイミングあったよね、と。

規約が大ボリュームだった割にコードレビューなかったんだよな、このプロジェクト・・・

キャッシュエントリーの生存期間が、値ではなくキーへの外部からの参照によって決定する場合だけ、WeekHashMapが有用

WeekHashMapはキーが弱参照になっているMap実装でして、キーが参照されなくなった後、ガベージコレクションが発生するとそのキーオブジェクトは削除されます。

実行結果

参照を取り除いたキーオブジェクトが消えました。キーを再利用しないキャッシュはこれでいいということです。

本書ではjava.lang.refを使う高度な手もあると言っています。java.lang.refには弱参照オブジェクト(WeakReference)、ソフト参照オブジェクト(SoftReference)といったものがあります。それらを使い分けてGC管理してね、ということです。

広告
  • LINEで送る