メモリの問題の分析

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 を実行します。次に、CRX java プロセスのパラメーターとして、-XX:+HeapDumpOnOutOfMemoryError が表示されているかどうかを確認します。

ディスク容量の制限により、ヒープダンプの生成に別のディレクトリを指定する必要がある場合は、-XX:HeapDumpPath=/path/to/generate/heapdump パラメーターを追加して、jvm にファイルの配置場所を指示することもできます。

デバッグ関連の jvm パラメーターについては、 こちらを参照してください。
手動でヒープダンプを生成する
Sun/Oracle JVM

ヒープダンプを手動で生成するには、次のコマンドを実行します(jmap および jps は、jdk ホームディレクトリの bin フォルダーにあります)。

  1. ヒープダンプを生成する java プロセスの pid を調べます。

    • Unix または Linux では、ps -ef | grep java または jps -l を使用して実行できます
    • Windows では、Ctrl+Shift+Esc を押してタスクマネージャーを開き、 表示 に移動して 列を選択 に移動 PID (プロセス ID) または jps -l を実行できます
  2. 次の 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 メモリアナライザー)があります。

このツールは、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 ヘルプ センター > ホットスポット VM のトラブルシューティング ガイド
[ 2]  Oracle.com > javas > DebuggingOptions

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f