java.lang.OutOfMemoryError: GC limit exceeded
Tomcatにデプロイされた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 にインポートされたヒープ ダンプのスクリーンショットです。