26

私はかなり紛らわしい GC ケースに遭遇しました。Eden スペースが 100% 使用されているのに、0% のサバイバー スペースが使用されています。Eden がいっぱいになると、ガベージ コレクションがトリガーされるはずですよね?

GC デーモンの実行が妨げられる場合はありますか? 100% CPU のような?

を使用してjdk-1.7います。

原因は何ですか?以下は jmap の出力です。

また、 を使用してより詳細なメモリ使用量を取得しようとしましたjmap -histo -Fが、CPU 使用率が 0% に低下し、Java プロセスに到達できなくなりました。

using thread-local object allocation.
Parallel GC with 18 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 12884901888 (12288.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 85983232 (82.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 4265738240 (4068.125MB)
   used     = 4265738240 (4068.125MB)
   free     = 0 (0.0MB)
   100.0% used
From Space:
   capacity = 14352384 (13.6875MB)
   used     = 0 (0.0MB)
   free     = 14352384 (13.6875MB)
   0.0% used
To Space:
   capacity = 14680064 (14.0MB)
   used     = 0 (0.0MB)
   free     = 14680064 (14.0MB)
   0.0% used
PS Old Generation
   capacity = 8589934592 (8192.0MB)
   used     = 8589931920 (8191.997451782227MB)
   free     = 2672 (0.0025482177734375MB)
   99.99996889382601% used
PS Perm Generation
   capacity = 41353216 (39.4375MB)
   used     = 41079056 (39.17604064941406MB)
   free     = 274160 (0.2614593505859375MB)
   99.33702858805468% used
4

4 に答える 4

11

あなたのヒープ構成を見たとき、私はそれを見つけました

MaxNewSize = 17592186044415 MBは正しくありませんが、バイト単位でなければなりません。

ほとんどすべての世代が同時に満杯であり、Collector両方の世代を収集しようとしているため、互いにブロックされていることがわかります。

以下のパラメータでメモリを調整することをお勧めします。

-XX:NewRatio=3 - the young generation will occupy 1/4 the overall heap
-XX:NewSize - Calculated automatically if you specify -XX:NewRatio
-XX:MaxNewSize - The largest size the young generation can grow to (unlimited if this value is not specified at command line)

edenまた、オブジェクトが'tenured' 世代からコピーされるときにタイム コレクターを提供する、いくつかのサバイバー スペースを使用することをお勧めします。

-XX:SurvivorRatio=6 - each survivor space will be 1/8 the young generation

生存者スペースが小さすぎる場合、コレクションのコピーは、Tenured 世代に直接オーバーフローします。

詳細については、このリンクを参照してください。

編集:

-XX:NewRatio=3- 若い世代は全体のヒープの 1/4 を占有します

計算:

    y/t=1/3

    y+t=h
    y+3y=h
    y=h/4

 t=tenured
 y=young
 h=heap
于 2012-07-05T08:05:19.157 に答える
6

スレッド ローカル バッファーは、eden 空間から割り当てられます。バッファーが割り当てられるとすぐに、eden スペースの空きスペースが完全に減少します。これは、ほとんど空の TLAB が多数あることを意味しますが、eden スペースは満杯のように見えます。GC は、eden スペースに十分な空きスペースがない場合にトリガーされます。

TLAB をオフに-XX:-UseTLABすると、パフォーマンスが低下しますが、スペースの使用状況をより正確に把握できます。

于 2012-07-05T08:11:24.320 に答える
3

SurvivorRatio の計算:

SurvivorRatio=6 の場合、(One SurvivorSpace : Eden) = (1:6) の比率。
したがって、サバイバーは 2 つ (2 つの部分) を取り、エデンには 6 つの部分があります。なので全部で8パーツ。
したがって、40 MB の若い世代がある場合、Eden は (6/8 * 40) MB で、1 人の生存者は (1/8 * 40) MB になります。

SurvivorRatio=7 の場合。合計パーツは (7 + 1 + 1 = 9) です。Eden は (7/9 * 40)MB で、生存者は (1/9 * 40)MB になります

理論的には

    The SurvivorRatio parameter controls the size of the two survivor spaces.
 For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space 
and eden to be 1:6, each survivor space will be one eighth of the young 
generation.

数学的に

S - サバイバー
E - エデン
Y - 若い世代

if SurvivorRatio=6
then S / E = 1/6
         E = 6S

2S + E = Y
2S + 6S = Y
S = Y / 8

効果

SurvivorRatio 値を大きくすると、Survivor のスペースが少なくなり、eden スペース オブジェクトが古い/tenured gen に直接プッシュされます。マイナー GC を介してサバイバー スペースで撃たれた生きているオブジェクトを除外する機会が少なくなります。また、これによりフル GC の回数が増える可能性があります。

これをより低い値に減らすと、eden スペースが少なくなり、マイナー GC が頻繁に行われます。

マシンがマルチコアマシンであっても、GC にシングルスレッドのみが使用されるシリアル GC アルゴリズムを使用している場合は特に、マイナー GC にかかる時間が長くなることに注意してください。

-XX:+UseAdaptiveSizePolicyまた、実行時に JVM 自身の SurvivorRatio を決定することに注意してください。

于 2015-02-09T22:55:37.987 に答える
2

ちょっと考えてみましたが、旧世代も満員です。Edenをクリーンアップしようとする代わりにGCが、OOMを回避するために旧世代をクリーンアップしようとしてフルGCを実行するのに忙しい可能性があります。

于 2012-07-05T07:54:28.683 に答える