Javaパフォーマンス改善 - Full GCの原因とその解決方法について
2011/12/09 17:34Update
Javaパフォーマンス改善につながるヒープ領域、GC、Full GC、Full GCの回避策などについて解説します。
■ヒープ領域について
ヒープ領域は
◇ 若い世代(New 領域)
※New領域はさらにEden領域、Survivor(From領域、To領域)という3つの領域に分割されています。
◇ 古い世代 (Old 領域) :寿命の長いオブジェクトがこの領域に配置されます。
があります。
ヒープ領域のほか、クラスのメタ情報を格納するPermanent 領域もあります。
■GCについて
GCは、Garbage Collection(ガベージ・コレクション)の略称で、メモリ領域の開放を行う役割を担います。
「Scavenge GC」:NEW領域を対象とした短時間で終了するガベージ・コレクションで、New 領域が不足した場合に実行されます。
※Scavenge GCの実行時間が0.1秒未満がベスト
「Full GC」:Old 領域が不足した場合実行されます。 Full GCが行われている間は、他の処理ができなくなり、システムは一時的に停止し応答しません。
※Full GCの実行時間が1秒未満がベスト
■Full GCだと思われる現象
数秒~数十秒間でWebシステムは一時停止して応答がない状態で、Full GCの可能性が高いと思われます。
Java VMの仕組み上で、Full GCによるシステムの一時停止現象は一般に「Stop the World」と呼ばれています。
■Full GCの原因
JavaヒープのOld 領域かPermanent 領域が一杯になっている(枯渇)時にFull GC が発生します。
※JDK1.5.0+であればPermanent領域は一杯になることはないようで Old 領域を疑った方がよいかもしれません。
■Full GCの確認
JVMの起動パラメータにGCを出力するように設定することで、GCやFull GCログが出力されますので、Full GCがどの頻度で行われたかを確認できます。
◇設定例:
-verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
※-XX:+HeapDumpOnOutOfMemoryError (JDK1.5+)
※-XX:+HeapDumpOnOutOfMemoryError (JDK1.5+)
◇Full GCの出力例:
228.004: [Full GC 228.004: [Tenured: 168230K->167535K(1699072K), 1.2345678 secs]
167459K->64535K(1038336K), [Perm : 53247K->53247K(53248K)], 1.3357874 secs]
167459K->64535K(1038336K), [Perm : 53247K->53247K(53248K)], 1.3357874 secs]
■Full GCの回避策
JavaヒープのOld領域を枯渇させないようにすること。
◇プログラムを見直す
1)オブジェクトをできるだけ使い回さない。使いまわされると、Old 領域に割り当てられる可能性も高くなりますので、Full GC が発生しやすくなります。
2)オブジェクトの寿命を短くにする。セッション理由は同上2)
3)長く利用する使いまわしオブジェクト(セッションや接続プールなど)の数やサイズを減らす:Old領域を満杯にならないようにする。
※セッションタイムアウト時間は必要以上になっていないか
※セッションに必要以上(数、サイズ)のオブジェクトが格納されていないか
※アプリケーション スコープのオブジェクトは必要以上(数、サイズ)に格納されていないか
◇JavaVMの設定を見直す
1)一時(短命)オブジェクトは多い場合、New 領域を大きめ取る。
2)使いまわしオブジェクトは多い場合、Old領域を大きめ取る。
3)Scavenge GCは
New領域が大きすぎる可能性があるので、-Xmn(-XX:NewSize)、-XX:MaxNewSizeを減らす。
◇※GC関連の基本的なJVMオプション
-Xms ヒープ領域の初期値
-Xmx ヒープ領域の最大値。一般的に、-Xmsと同値にする
-Xmn NEW領域(Eden、From、To)の初期値。
-XX:NewSize New 領域の初期値。同-Xmn
-XX:MaxNewSize New 領域の最大値。一般的に、-XX:NewSizeと同値にする。
-XX:PermSize Permanent 領域の初期値
-XX:MaxPermSize Permanent 領域の最大値。一般的に、-XX:PermSizeと同値にする。
-XX:NewRatio New 領域と Old 領域の比率
-XX:SurvivorRatio New 領域と Survivor 領域の比率。SurvivorRatio=Eden÷Survivor
-verbose:gc(-Xloggc:出力先) GCログ出力指定
-XX:+PrintGCTimeStamps GCログにタイムスタンプ(Java起動時からの経過時間)出力
-XX:+PrintGCDetails 詳細なGCログを出力
-XX:+PrintClassHistogram SIGQUITシグナル(kill -3 pid)受信時にヒープ統計情報を出力。-verbose:gc(-Xloggc:出力先)と併用必須。
-XX:+HeapDumpOnOutOfMemoryError OutOfMemoryError発生時にヒープダンプを出力 (JDK1.5+)
-XX:+UseParallelGC マルチコアCPUまたは複数CPUの場合は、パラレルGCをマルチスレッドで実行を有効にする
※-XX:PermSize/-XX:MaxPermSize:-Xms/-Xmx範囲に含まれないことをご理解ください。
-Xmx ヒープ領域の最大値。一般的に、-Xmsと同値にする
-Xmn NEW領域(Eden、From、To)の初期値。
-XX:NewSize New 領域の初期値。同-Xmn
-XX:MaxNewSize New 領域の最大値。一般的に、-XX:NewSizeと同値にする。
-XX:PermSize Permanent 領域の初期値
-XX:MaxPermSize Permanent 領域の最大値。一般的に、-XX:PermSizeと同値にする。
-XX:NewRatio New 領域と Old 領域の比率
-XX:SurvivorRatio New 領域と Survivor 領域の比率。SurvivorRatio=Eden÷Survivor
-verbose:gc(-Xloggc:出力先) GCログ出力指定
-XX:+PrintGCTimeStamps GCログにタイムスタンプ(Java起動時からの経過時間)出力
-XX:+PrintGCDetails 詳細なGCログを出力
-XX:+PrintClassHistogram SIGQUITシグナル(kill -3 pid)受信時にヒープ統計情報を出力。-verbose:gc(-Xloggc:出力先)と併用必須。
-XX:+HeapDumpOnOutOfMemoryError OutOfMemoryError発生時にヒープダンプを出力 (JDK1.5+)
-XX:+UseParallelGC マルチコアCPUまたは複数CPUの場合は、パラレルGCをマルチスレッドで実行を有効にする
※-XX:PermSize/-XX:MaxPermSize:-Xms/-Xmx範囲に含まれないことをご理解ください。
◇※NEW領域の調整について
NEW領域:-Xmnオプションを用いてNEW領域(Eden、From、To)のサイズを指定します。
NEW領域の割合は、最大ヒープ・サイズ(-Xmxオプション)の1/4から1/2の間で設定することが一般的となります。
◇システム構成を見直す
1)システムを冗長化する
2)Full GCさせないアプリサーバで対応
などの方法があります。
設定例:
export CATALINA_OPTS="-server -Xmx256M -Xms256M -XX:NewSize=128M -XX:MaxNewSize=128M -XX:SurvivorRatio=2 -Xloggc:/var/log/gc.log"
-Xms=1024m -Xmx=1024m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:NewSize=320m -XX:MaxNewSize=320m -XX:SurvivorRatio=2 -XX:TargetSurvivorRatio=80
-Xms=1024m -Xmx=1024m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:NewSize=320m -XX:MaxNewSize=320m -XX:SurvivorRatio=2 -XX:TargetSurvivorRatio=80
メモリ関連ツール
◇ヒープダンプ情報出力ツール
・jmap:ヒープダンプを行うツール
・jconsole
・hprof
・jstack:スレッドダンプを行うツール
※jps:JavaのPIDを確認するツール
※jinfo:Java VM の構成情報を参照、設定するためのツール
◇プロファイラ ツール
・visualvm
・NetBeans Profiler
・jprofiler
◇統計&分析ツール
・Eclipse Memory Analyzer
・HeapAnalyzer
・HAT
・jstat
・jhat
・gcLogViewer
・SAP Memory Analyerツール
・IBMR HeapAnalyzer
参考資料
Java OutOfMemoryError対策
java.lang.OutOfMemoryError: PermGen space及びJava PermGenについて
ガーベジ・コレクション:GC ( Garbage Collection ) についての簡単な説明と調査方法
Javaメモリ、GCチューニングとそれにまつわるトラブル対応手順まとめ - 日記のような何か
Full GC発生を抑止するメモリ管理技術「PDF」
@IT:チューニングのためのJava VM講座(後編)
「Java のヒープサイズ」についての簡単な説明
ise0615 blog: JAVAヒープサイズ・GCチューニングのまとめ
肥え続けるTomcatと胃を痛めるトラブルハッカー (2/3) - @IT
Java HotSpot VM Options
Oracle JRockit JVM のチューニングの初歩
@IT:事例に学ぶWebシステム開発のワンポイント(6)
@IT:事例に学ぶWebシステム開発のワンポイント(9)
Sponsored Link
Comments
- Relative Articles
- Javaパフォーマンス・チューニング - JVM オプション | ヒープ サイズの設定 - (2009/06/29 17:36)
- JVMの性能(CPU、メモリ)をビジュアル表示できるVisualVMツールの使い方 - (2009/10/23 10:41)
- JMX に準拠したJVM監視ツール jconsole の使い方 - (2009/10/23 14:13)
- java.lang.OutOfMemoryError: PermGen space及びJava PermGenについて - (2011/12/07 13:26)