10

java.lang.OutOfMemoryError: GC limit exceededTomcatにデプロイされたWebアプリの高負荷時に何が発生するかを調査しようとしていました. ヒープ サイズは 8 GB に設定されました ( -Xms2048m -Xmx8192m)

ある時点で、GC アクティビティのオーバーヘッドが原因で、アプリケーションが応答しなくなります。フル GC が連続して複数回発生していることをログで確認できました。そこで、次のコマンドでヒープダンプを取得しました(jmap -F -dump:format=b,file=/root/dump2.hprof 4963)。ダンプを含むファイルのサイズは 9GB でした。ダンプが取得された後 (アプリは約 45 分間フリーズされました)、OutOfMemoryErrorスローされるまで複数のフル GC が発生しました。

GC アクティビティのログ サンプルを次に示します。

[Full GC [PSYoungGen: 932096K->875513K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6467961K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.3954040 secs] [Times: user=47.60 sys=0.43, real=12.39 secs]
[Full GC [PSYoungGen: 932096K->890562K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6483009K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.6131900 secs] [Times: user=48.45 sys=0.49, real=12.61 secs]
[Full GC [PSYoungGen: 932096K->895268K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6487715K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.9488670 secs] [Times: user=49.61 sys=0.46, real=12.95 secs]

Heap
 PSYoungGen      total 1864128K, used 896698K [0x0000000755560000, 0x0000000800000000, 0x0000000800000000)
  eden space 932096K, 96% used [0x0000000755560000,0x000000078c10e8a8,0x000000078e3a0000)
  from space 932032K, 0% used [0x000000078e3a0000,0x000000078e3a0000,0x00000007c71d0000)
  to   space 932032K, 0% used [0x00000007c71d0000,0x00000007c71d0000,0x0000000800000000)
ParOldGen       total 5592448K, used 5592447K [0x0000000600000000, 0x0000000755560000, 0x0000000755560000)
  object space 5592448K, 99% used [0x0000000600000000,0x000000075555ff30,0x0000000755560000)
PSPermGen       total 262144K, used 112285K [0x00000005e0000000, 0x00000005f0000000, 0x0000000600000000)
  object space 262144K, 42% used [0x00000005e0000000,0x00000005e6da7530,0x00000005f0000000)

heap dump is taken (ca 45minutes freeze)
[Full GC [PSYoungGen: 932096K->903362K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6495810K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 2883.9864390 secs] [Times: user=49.41 sys=0.47, real=2884.17 secs]
[Full GC [PSYoungGen: 932096K->897728K(1864128K)] [ParOldGen: 5592447K->5592444K(5592448K)] 6524543K->6490173K(7456576K) [PSPermGen: 112288K->112288K(262144K)], 13.3092680 secs] [Times: user=50.75 sys=0.40, real=13.31 secs]

ヒープ ダンプを分析するために、Eclipse メモリ アナライザー (MAT) で開きました。残念ながら、MAT はヒープ サイズが 363.2MB (概要タブまたはヒープ ダンプの詳細タブ) であると表示しますが、GC ログによると、ヒープは 6467961K (6.4G) までいっぱいでした。Unreachable Objects Histogram は合計 75 511 736 (75 MB) を示します。ヒストグラム ビューでも、浅いヒープの合計が 380 837 136 であることが確認されました (363.2MB)

私の質問は、GC がメモリを再利用できない場合、MAT がヒープ ダンプからすべてのオブジェクトを表示しないのはなぜですか?

env details:
Eclipse Memory Analyzer Version 1.2.1
heap dump taken on
java version "1.7.0_13"
Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

以下は、MAT にインポートされたヒープ ダンプのスクリーンショットです。

4

5 に答える 5

15

既定では、MAT は到達不能オブジェクトを表示しません。

このオプションを有効にするには、[設定] -> [メモリ アナライザー] -> [到達不能オブジェクトを保持] に移動します。オプションが有効になったら、ヒープを再度ロードします。

オプションが有効になると、完全なヒープが表示されます。私も同じ状況にあり、オンラインで多くの情報を得ることができず、マネージャーが選択肢を示してくれました。

于 2013-12-05T16:24:21.417 に答える
2

デフォルトでは、MAT はすべてのUnreachable オブジェクトをそのビューから非表示にします。これらのオブジェクトは既にガベージ コレクションの対象としてマークされているためです。

Unreachable オブジェクトは、次のビューでアクセス可能にすることができます。

  1. スナップショットを閉じる
  2. [ウィンドウ] > [ヒープ ダンプ履歴] を右クリックし、[インデックス ファイルを削除] を使用してヒープ ダンプを選択します。
  3. [ウィンドウ] > [設定] > [メモリ アナライザー] を使用して、[到達不能なオブジェクトを保持する] を選択します。
  4. ヒープ ダンプを再度開くと、ヒープ ダンプが再解析されます。
  5. [Java 基本] > [GC ルート] クエリを選択します。
  6. 「到達不能オブジェクト」行を選択します。
  7. その行で「Show Retained Set」クエリを実行します。

これにより、通常は到達できず、次の機会にガベージ コレクションされるすべてのオブジェクトのヒストグラムが表示されます。これらのオブジェクトは現在スナップショットにあるため、より詳細に調べることができます。

詳細については、 Eclipse MAT リファレンス - 到達不能オブジェクトを参照してください。

于 2021-03-10T11:59:50.563 に答える
0

実際、 java.lang.OutOfMemoryError: GC limit exceeded問題のトラブルシューティングを行う際に jmap ユーティリティを使用することはお勧めしません。JVM が破棄されている間 (メジャー コレクションの数が多すぎる)、このアプローチで問題が発生するのを見てきました。

代わりに次のアプローチを試して、MAT の解析と分析プロセスからより良い結果が得られるかどうかを確認してください。

  • 次の JVM HotSpot パラメーター -XX:+HeapDumpOnOutOfMemoryError を追加します。
  • 問題を再度再現し、OOM イベントを待ちます。ヒープ ダンプの生成が大幅に高速化され、データの価値と有効性が向上します。
  • JVM は、OOM イベントに続いてJVM ヒープ ダンプ(HPROF 形式) を生成します。
  • JVM ヒープ ダンプを MAT に再度読み込み、ヒープ フットプリントが大きくなるなど、より良い結果が得られるかどうかを確認します。

よろしく、PH

于 2013-10-08T18:07:04.910 に答える