2008年12月17日水曜日

Java Out Of Memoryが発生したときのアプローチ

以下、Webからの抜粋

【OutOfMemoryError が出た時のアプローチ(①)】
OutOfMemoryError はメモリの使用量がヒープメモリサイ ズの指定を超えると発生します。
OutOfMemoryError に陥るケースは二つあります。

 (A) 不要なオブジェクトが無駄にメモリに残っている場合
 (B) ヒープサイズの絶対量が不足している場合
 以下にそれぞれの対処を記します。

  (A)不要なオブジェクトが無駄にメモリに残っている場合
  この場合、まず問題のあるオブジェクトを 見つけます。
  問題のあるオブジェクトに対して、以下の対処を施します。

   1. 不要になったオブジェクトは参照を破棄 ( 変数に null を代入 ) する

使い終わった不要なオブジェクトをメモリから解放し、メモリを有効活用でき るようにします。
Java の場合、使い終わった不要なオブジェクトはガーベージコレクション ( 以下 GC ) によりメモリから解放されます。
通常、GC が行われることで OutOfMemoryError は発生しません。

この GC は不定期に実行されるもので、「不要となったオブジェクト」を解放 します。
GC は解放の前に「不要であるかどうか」判断します。

GC が実行されても、GC が不要と判断しない限り、オブジェクトはメモリから 解放されません。

GC は「オブジェクトへの参照が無い」事を見て不要と判断します。

GC にメモリを解放してもらうためには、プログラマ上では「この時点でこのオブジェクトはもう要らないな」 と判断できるところで、
そのオブジェクトへ の参照がない状態すなわち変数の値を null 値にします。

    2. Session オブジェクトに大きなオブジェクトを格納する事は極力避ける

SSJS、サーブレット、JSP の場合、Session にオブジェクトを格納して 画面間でデータを持ちまわったり画面遷移の制御をする
と思います。

Session に格納する時は、必要な分だけに留めるべきです。

アクセスが集中した時、セッション数が増えます。 大きなオブジェクトを格納するとセッションの数に比例してメモリ使用量が

大きく増加することとなる。

    3. Session に格納した場合、不要となった時点で削除する

格納したオブジェクトは不要になった時点で、セッションから削除します。

削除を怠れば、セッションタイムアウト時間までJava VM のメモリ上に残ったままになります。

(B) ヒープサイズの絶対量が不足している場合
上記(①)で対処を行ってもなお OutOfMemoryError が発生する場合は、システム の規模等に対し、ヒープサイズが不足しています
ので -Xms、-Xmx パラメータの値を調整して ヒープサイズを大きくとります。この時に設定する値は-Xms、-Xmxともに同じ値を設定する。

パラメータ -verbose:gc を使用することでFullGC の発生頻度、メモリ使用量、GC の 種類が確認できますので、得られた結果からチュー
ニングを行います。 設定できる値はディスクスワップの発生しないサイズ、すなわち物理メモリサイズです。
最大負荷をかけるテストを行い、FullGC の頻度と FullGC の実行時間を確認し、以下を 目安に調整します。

* FullGCの発生頻度が多い場合
ヒープサイズを大きくとる
Java VMパラメータでNew領域の内容を調整し、オブジェクトがOLD領域に移動しないようにする。

※Java VMパラメータにつきましては、以下のURLがチューニングの参考になります。
http://java.sun.com/docs/hotspot/
http://www.ingrid.org/java/jserv/performance
http://www.atmarkit.co.jp/fjava/rensai2/webopt06/webopt06.html
http://www.atmarkit.co.jp/fjava/rensai2/webopt09/webopt09.html


(2)Java VMパラメータチューニングによる安定動作の運用事例
現在まで弊社に届いた情報を元に安定的な稼動に成功している事例に共通する事項をまとめてみました。

以下の事項は、安定稼動が達成されている動作環境要件 と安定稼動を実現する為に行われたSun JavaVMのパラメータチューニング

についてより具体的な情報を記載いた します。
(A)動作環境要件

intra-martシステム稼動前のFreeメモリ容量(1サーバ当りの容量で仮想メモリは含みません。): 2GByte以上
(B)安定的な稼動を実現したSun JavaVMのパラメータ

Unix系
-Xms=1024m -Xmx=1024m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:NewSize=320m -XX:MaxNewSize=320m
-XX:SurvivorRatio=2 -XX:TargetSurvivorRatio=80

Windows系
-Xrs -Xms=1024m -Xmx=1024m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:NewSize=320m -XX:MaxNewSize=320m
-XX:SurvivorRatio=2 -XX:TargetSurvivorRatio=80

※上記パラメータは2行で表現されておりますが 実際に設定される場合は一行です。