X

An Oracle blog about WebLogic Channel

OutOfMemoryErrorの対応方法/Heap解析ツール(MAT)の使い方

WebLogic勉強会 通信

WebLogic Serverファンの皆様、こんにちは、WebLogic Server勉強会通信です。
2014年6月24日に開催された
「第48回WebLogic Server勉強会@東京」
の後半セッションで
CTCの橋本 和俊氏が発表した
「OutOfMemoryErrorの対応方法/Heap解析ツール(MAT)の使い方」
をレポートします。
このセッションで橋本氏は度々見かける「OutOfMemoryError (OOME)」が発生する理由、原因追究方法を分かりやすく
説明しました。Javaアプリケーションのトラブルシューティングや性能評価の際に
GCの状況をモニタリングしながらヒープサイズを調整したり、JVMのメモリ使用推移を監視することが有効です。
また、メモリリークを発見するための「Eclipse Memory Analyzer(MAT)」も役立つでしょう。
JVM起動時の適切なオプション設定、GCログの採取とモニタリング、Heap Dumpの取得と分析方法などをマスターして、
OutOfMemoryError (OOME)に備えましょう。
(日本オラクル Fusion Middleware事業統括本部 佐々木 政和)

OutOfMemoryError(OOME)とは

OutOfMemoryError(OOME)はJVMがメモリ不足時に出力するエラーです。
OOMEが発生した場合には、JVMは正常に動作できない可能性があります。
このセッションでは、OOMEの発生原因や対処方法を習得するために、
JVMのメモリ管理方法、GCログの出力設定方法、GCログの見方、
OOMEの発生原因の調査方法、
Heap Dump の取得方法とその分析方法などを説明します。

オラクルはHotSpot(Sun JDK)とJRockitそれぞれのJVMを提供しています。
JVM毎にメモリ管理方法や起動時のオプションが異なります。
今回は、HotSpot(JDK 7まで)を前提にして説明します。
HotSpotは、Heap, Permanent, C Heapの3つのメモリ領域に分けてアプリケーションの
メモリ管理を行っています。
Heapは、JVMのオブジェクト(String等)や配列の実体が格納される領域です。
JVMはこの中をYoung領域とOld領域の二つに分けて管理しています。
Permanent(以下Perm)は、JVMのクラス情報などのMeta情報が格納される領域です。
C Heap(Native)は、最適化されたコード/JNIなどが格納される領域です。

JVMの重要な役割としてアプリケーションのメモリ管理があります。
これはアプリケーションの中で使用済みで参照されないオブジェクトのメモリを
開放する仕組みです。これをGarbage Collection(GC)と呼びます。
GCにはYoung領域のGCとHeap全体のGCであるFull GCがあります。

正常に動作している環境では、GCサイクルで不要なメモリ空間を解放するので、
次にアプリケーションが必要なメモリ空間は確保できます。ところが、GCを行ってもメモリが
確保できない場合が起こりえます。その際に、JVMはメモリ不足(OOME)を発生させます。
OOMEはJavaのメモリ不足を示すエラーですが、領域により下記の種類があります。

OOMEの発生に備えた準備

OOMEが発生した際にはJVMの動作が不安定になり,
再起動しなければ解消されません。また、OOME後の動作についてはサポート対象外になります。
根本的な原因が特定できない場合、たとえ再起動して動作したとしても同じことが発生する可能性があり
一時的な解消でしかありません。
原因を特定させるためには、OOME発生時のみのスレッドダンプだけでは不十分で、
時系列で監視しているメモリ使用量の遷移、特にGC前後のメモリ使用量の増減などを
分析する必要があります。

WebLogic Serverの運用においてコンソールログの設定は必ず行ってください。
OOMEはコンソールログにのみに出力される場合がありますので、
“標準出力や標準エラー出力のロギングのリダイレクトを有効化”を使用せずに、
コンソールログの出力を推奨します。
また、GCログの遷移を分析するために、次の表のようにGCログの出力用オプションを
適切に設定します。7u2,6u34以降であれば、GCログのローテーション用オプションを
使用することができます。

GCログでHeap使用量の推移を見る

GCログに記録されるのは、日付: 起動してからの秒時間: GC/Full GC、
Young領域の使用量、現在のYoung領域の最大値、
Old領域の使用量、現在のOld領域の最大値、
Permの使用量、現在のPermの最大値、GCにかかった時間
(user/sys はCPU時間、real が実際にかかった時間)です。
これをグラフで表示すると、下図のように遷移を見ることができます。

GCログ分析後の推奨アクション

Heapが足りない場合:Heapが1GBぐらいの場合は単純にプログラムに対するHeapが足りない場合もあるため、
まずはHeapを増やして(-Xms/-Xmx)再現するかどうかの検証をすることが有効です。
Heapが大きいとHeap Dump等を解析する時に問題が顕在化し、調査が行いやすくなります。
逆に大きすぎると解析しづらいので、ほどほどに…
Heapを大きくするとOOMEが発生するまで時間が延びます。原因不明ならばHeapを大きくして
毎日再起動等での対処もありといえばありです。(あまり推奨したくないですが。)
32bit JVMを使用している場合は2GB制限を考慮し、Heap は1.5GBまでとりあえず上げてみてください。
64bitならばOSの空き物理メモリ量と相談しましょう。

Permが足りない場合:まずは増やしてみましょう。
-XX:PermSize(初期値) と -XX:MaxPermSize(最大値)
基本的に初期値=最大値に設定してください。
増やしても足りない場合は読み込まれているクラス情報を確認する等の別の視点からの調査が必要です。

C Heapが足りない場合:64bit JVMに変更すればとりあえず制限はほぼありません。
32bit JVM の場合はHeapやPermを減らしてみるのも一つの手段です。
C Heapの最大量は[プロセスの最大メモリ量] – [Heap最大量] – [Perm最大量]のため、
Heap/Permを減らせば最大量は増えることになります。
ただし、他のOOMEが出ないように注意してください。

Heap Dumpの取得方法とMAT分析ツール

OOME時にHeap Dumpを出力するオプションを使用してHeap Dumpを取得します。
またスライドP.30のように動作中にHeap Dumpを取得する方法も提供されています。
Eclipse Memory Analyzerをダウンロードして、Heap Dump(正常時とOOME発生時)の
差分比較を行うことで、メモリリークなどの障害を見つけ出すことができます。(スライドp.31-50参照)

まとめ

このセッションではOutOfMemoryError (OOME)とは何か、JVM起動時の適切なオプション設定、GCログの採取とモニタリング、Heap Dumpの取得と分析方法などを説明しました。アプリケーションのデバッグ、テストの段階でGCログの遷移からJVMのメモリ使用状況をモニタリングして、メモリーリークなどの不具合の発見も可能です。JVMやWebLogic Serverの設定オプションの確認や各種のログ出力設定、内容の分析などこの機会にもう一度レビューされてはいかがでしょうか。

「お悩み相談室」をご活用ください

毎回、WebLogic Server勉強会では、最後に「お悩み相談室」として
Oracle WebLogic Serverに関する疑問、質問に答えるセッションを行っています。
普段、WebLogic Serverのアプリケーション開発、運用管理で困っていること、
悩んでいることなどありましたらドシドシお寄せ下さい。回答者は、講師、
Oracle ACE、エキスパートの
皆様

お願いしています。
他の参加者の皆様も同じ悩みをお持ちの方がいらっしゃるかもしれません。どんなことでも構いませんのでよろしくお願いします。
申し込み時の「質問欄」にご記入ください。次回は8月27日に開催します(間もなく参加登録ページを公開予定です)。




Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.