2019年5月5日

第7章 ヒープのベストプラクティス

一般的には、オブジェクトを生成する回数を減らし、必要なくなったらすぐに廃棄すべきというルールがある。一方、同じ種類のオブジェクトをなんども生成するのは全体としてのパフォーマンスの悪化に繋がります。このようなオブジェクトを破棄せずに再利用するようにすれば、パフォーマンスは大きく向上します。

ヒープの分析

ヒープヒストグラム

どの型のオブジェクトが多くのメモリを消費しているかという点について、分析が必要です。このための最も簡単な方法が、ヒープヒストグラムを利用するというものです。ヒープヒストグラムを使えば、アプリケーション内で使われているオブジェクトの数を手早く確認できます。 ヒープヒストグラムのデータはとても小さいので、自動化されたテストの中で毎回出力されるようにするとよいでしょう。

ヒープダンプ

ヒープヒストグラムよりも詳細な分析が必要な場合には、ヒープダンプが必要になります。 ヒープの分析では、まず保持メモリ量(retained memory)について調べるのが一般的です。保持メモリ量とは、該当するオブジェクトがガーベジコレクションの対象になった場合に解放されるメモリ量を表します。 ヒープの中で保持メモリ量の多いオブジェクトはドミネータ(dominator)と呼ばれます。 一般的な指針としては、コレクションのエントリではなくコレクション自体のオブジェクトから探索を初めて、最大のコレクションを探すようにしましょう。

OutOfMemoryError

OutOfMemoryErrorは次のような状況で発生します。

[ヒープダンプの自動取得]
OutOfMemoryErrorの発生は予測ができないため、いつヒープダンプを取得するべきか判断するのは困難です。そこで、JVMには次のようなフラグが用意されています。

-XX:+HeapDumpOnOutOfMemoryError
  OutOfMemoryErrorの発生時にヒープダンプを生成
-XX:HeapDumpPath=パス
  ヒープダンプの出力先を指定
-XX:+HeapDumpAfterFullGC
  フルガベージコレクションの後にヒープダンプを生成
-XX:+HeapDumpBeforeFullGC
  フルガベージコレクションの前にヒープダンプを生成

アプリケーションはオブジェクトを追加するだけで解放はしないため、コレクションは、メモリリークを最も発生しやすいです。不必要になったオブジェクトは積極的にコレクションから削除しましょう。

メモリの使用量を減らす

Javaでメモリを効率的に利用するには、まずヒープメモリの使用量を減らすべきです。ここでは、メモリの使用量を減らすための3つの方法(オブジェクトトのサイズを減らす、オブジェクトの初期化を遅らせる、canonicalオブジェクトの利用)を紹介します。

オブジェクトのサイズを減らす

オブジェクトはヒープ上の一定の領域を消費するので、メモリの使用量を減らすにはオブジェクトを小さくするのが一番の近道です。 オブジェクトのサイズを減らすには、インスタンス変数の数を減らすという方法とインスタンス変数のサイズを減らすという方法があります。nullのインスタンス変数も、一定のメモリを消費します。

Powered by Fruition