メモリの問題の分析
Java アプリケーションメモリの問題の原因を特定する方法を説明します。 ヒープダンプを自動的かつ手動で生成し、ヒープヒストグラムを生成して原因を特定できます。
説明 description
環境
Adobe Experience Manager
問題/症状
JAVA アプリケーションの実行が遅くなり、最終的にメモリが不足するか、ログまたはコンソール出力OutOfMemoryError: Java heap spaceまたはOutOfMemoryError: gc overhead limit exceededにエラーが表示されます。
解決策 resolution
原因
このような問題には多くの原因が考えられます。
考えられる原因の1つは、Java アプリケーションが、私たちの場合は、CRX / CQがJavaのデフォルトのヒープメモリ設定でコマンドラインから開始されたことです。 これは、jvm パラメーター -Xmx が指定されていないことを意味します。 CRX または CQ を実行するには、少なくとも 256 MB のヒープが割り当てられている必要があります。 これに該当する場合は、コマンドラインから起動して、ヒープメモリ設定が行われていることを確認してください。 例:
java -Xmx512m -jar *.jar
これに該当しない場合は、アプリケーションは、ガベージコレクション用に解放することなく、多くのオブジェクトを保持し過ぎている可能性があります。 これは、メモリリークと呼ばれます。詳しくは、こちらを参照してください。 Java アプリケーションのメモリの問題を分析する方法については、以下の節を参照してください。 ヒープダンプの作成:
ヒープダンプを自動的に生成
メモリ不足の実行時にヒープダンプを自動的に作成するには、jvm パラメーター-XX:+HeapDumpOnOutOfMemoryErrorを追加して、アプリケーションがOutOfMemoryErrorをスローしたときにヒープダンプを自動的に生成できます。 例:
java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar
これにより、Java プロセスのメモリ不足が発生するたびに、プロセスの作業ディレクトリにヒープダンプファイル (java_...hprof)が生成されます。 ヒープダンプが生成された後も、プロセスは実行し続けることができます。 通常、問題を分析するには、1 つのヒープダンプファイルで十分です。
メモ:CRX インスタンスを起動するために crx-quickstart/server/start スクリプトを使用している場合、CQ_JVM_OPTS 変数に -XX:+HeapDumpOnOutOfMemoryError を追加できます(この変数も同様にコメント解除されていることを確認してください)。 次に例を示します。
CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'
このパラメーターを追加して CRX インスタンスを再起動したら、新しい jvm オプションが設定されていることを検証します。 コマンドラインから ps -ef | grep java を実行します。 次に、-XX:+HeapDumpOnOutOfMemoryErrorがCRX Java プロセスのパラメーターとして表示されているかどうかを確認します。
ディスク容量の制限により、ヒープダンプの生成に別のディレクトリを指定する必要がある場合は、-XX:HeapDumpPath=/path/to/generate/heapdump パラメーターを追加して、jvm にファイルの配置場所を指示することもできます。
関連するjvm パラメーターのデバッグについては、こちらを参照してください。 ヒープダンプを手動で生成する Sun/Oracle JVM
ヒープダンプを手動で生成するには、次のコマンドを実行します(jmap および jps は、jdk ホームディレクトリの bin フォルダーにあります)。
-
ヒープダンプを生成するjava プロセスのpidを調べます。
- UnixまたはLinuxでは、
ps -ef | grep javaまたはjps -lを使用して実行できます - Windowsでは、タスクマネージャーを開いて
Ctrl+Shift+Escを押してから 表示 に移動し、列を選択に移動してから PID (プロセス識別子) またはjps -lに移動します
- UnixまたはLinuxでは、
-
次の jmap コマンドを実行します(
/path/to/generate/heapdumpfile.hprofをヒープダンプファイルを生成する場所に、1234を前述の手順で調べた pid に置き換えてください)。code language-none jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
IBM JVM
最初に、ユーザーシグナルに正しいダンプを生成するために、ダンプエージェントに関するデフォルトの JVM 設定を変更する必要があります。 ダンプにはいくつかの種類がありますが、通常、完全なメモリ分析を実行するには、完全な システムダンプ が必要です。 次の引数を追加します。
Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user
この「ユーザー」イベントは、JVMがオペレーティングシステムからSIGQUIT (Linux、AIX®、z/OS®、およびi5/OS™)またはSIGBREAK (Windows)信号を受信したときに発生します。
詳しくは、こちらにあるベンダーのドキュメントを参照してください。
警告: ヒープダンプファイルは大きく、最大ヒープ -Xmx jvm パラメーター設定とディスク上で最大サイズを同じにすることができます。 ダンプファイルが生成されるディレクトリに十分なディスク領域が割り当てられていることを確認します。 ヒープダンプの分析
ヒープダンプの分析に最適なツールはEclipseMAT (Eclipse Memory Analyzer) です。
このツールは、IBM JVM が生成したダンプを分析することはできません。 それについては、いくつかの可能性があります。 IBM HeapAnalyzerは、PHDまたはクラシック形式のヒープダンプに適しています。
完全なシステムダンプ分析を行うには、IBM Support Assistant Workbenchを使用し、上部にIBM Monitoring and Diagnostic Tools for Java - Memory Analyzerをインストールします。 ヒープヒストグラムは、Java クラスごとに使用されるライブオブジェクトとメモリの数を簡単に測定したものです。 残念ながら、Java インストールによっては、必要なツールが利用できないか、常に機能しない場合があります。 ヒープヒストグラムを作成するには、まずJava プロセスのプロセス IDが必要です。 取得するには、ps or (if available), run: ヒープヒストグラム を実行します
ヒープヒストグラムは、Java クラスごとに使用されるライブオブジェクトとメモリの数を簡単に測定したものです。 残念ながら、Java インストールによっては、必要なツールが利用できないか、常に機能しない場合があります。 ヒープヒストグラムを作成するには、まずJava プロセスのプロセス IDが必要です。 これを取得するには、ps を実行するか、(利用可能な場合は)次を実行します。
jps -l
このJava ツールは、実行中のすべてのJava プロセスのプロセス IDを取得します。 例:
327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar
ここで、次のコマンドを実行します。
jmap -histo 3313
このリストは、必要な合計メモリで並べ替えられています(シャロー:参照されるオブジェクトを除く)。 出力の最初の 20 行が最も興味深いものです。 出力例:
JVM version is 1.5.0_20-141
Iterating over heap. This may take a while...
Warning: skipping invalid TLAB for thread t@62211
Warning: skipping invalid TLAB for thread t@62467
...
SizeCountClass description
-------------------------------------------------------
1059290412916byte`[` `]`
1028584075255* ConstMethodKlass
628317658388char`[` `]`
604230414928int`[` `]`
4995752116201* SymbolKlass
422089675255* MethodKlass
41965126969* ConstantPoolKlass
29285606969* InstanceKlassKlass
26310086066* ConstantPoolCacheKlass
2395872149742org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId
14760087003java.util.HashMap$Entry`[` `]`
139612858172java.lang.String
107023244593java.util.HashMap$Entry
75398410036short`[` `]`
73546454org.apache.jackrabbit.core.query.lucene.DocId`[` `]`
7201927502java.lang.Class
64070413348com.day.crx.persistence.tar.index.IndexEntry
...
追加情報
問題の分析を支援するには、次の情報も必要です。
- CRX または CQ のバージョン(すべてのインストール済みホットフィックスのバージョン番号のリストを含む)。
- オペレーティングシステム、JVM ベンダーおよびバージョン。
参照
[ 1] Oracle ヘルプセンター> HotSpot VMのトラブルシューティングガイド [ 2] Oracle.com > javas > DebuggingOptions