5

背景情報;

サーバー;

130 GB RAM を搭載した新しい SLES 12 サーバーは、大規模なデータベース (150G + データ) で MySQL を実行することを目的としています。

サーバーは、いくつかの Java アプリケーションもホストします。

Java バージョン (Oracle のデフォルト) - Java(TM) SE ランタイム環境 (ビルド 1.7.0-b147) - Java HotSpot(TM) 64 ビット サーバー VM (ビルド 21.0-b17、混合モード)

次の問題に遭遇しました。

いくつかの特定の Java アプリケーションを実行すると、カーネル/システム CPU のピークが発生し、一定期間アプリケーションの速度が低下/停止します。時間の経過とともにメモリを単純に消費し、CPU を使用する Java アプリケーションを作成することで、これを再現しました。

調査によると、スローダウン中のインターアップの数が多いことが示されています (10000 ~ 25000)。

速度が低下するたびに、Java はさらにメモリーを獲得します。Java を固定メモリで開始するように設定すると、問題が軽減されるようです (-Xmx と -Xms を同じ値に設定します)。冗長なガベージ コレクションは、GC が起動しており、GC がトリガーになっている可能性があることも示しています。

GC とメモリの割り当ては、何らかの理由で非常に高価であり、ここからどこを見ればよいかわかりません。GC からの詳細:

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]

ローエンドの Linux サーバーで、GC を実行する同じプログラム (SLES、SUN の Java 1.6.0_11 を実行)。

[GC 1092288K->253266K(3959488K), 3.0125460 secs]    

減速時の TOP:

top - 11:23:33 up 87 days, 19:55,  5 users,  load average: 14.27, 4.50, 10.17
Tasks: 250 total,  39 running, 211 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us, 71.8%sy,  0.0%ni, 28.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    129033M total,   128576M used,      457M free,     1388M buffers
Swap:    32765M total,       13M used,    32752M free,   113732M cached

スローダウン中の vmstat (3.行から);

procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  13552 1714328 1422268 116462260    0    0    10     9    0    0  0  0 100  0  0
 1  0  13552 1241780 1422268 116462292    0    0     0     0  240  353  1  0 99  0  0
 1  0  13552 695616 1422268 116462292    0    0     0    17  419  431  3  0 97  0  0
55  0  13552 486384 1422268 116462292    0    0     0     2 20228  458  1 57 43  0  0
75  0  13552 476172 1422268 116462300    0    0     0     8 12782  684  0 70 30  0  0
65  0  13552 470304 1422268 116462304    0    0     0     0 13108  792  0 72 28  0  0

ローエンド サーバーと比べて、ハイエンド サーバーで GC が非常に高価なのはなぜですか? 手がかりを探すためのアイデアはありますか?

更新 - パラメータを呼び出します 2012-11-26パラメータを 呼び出します。

java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain

与える

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs]

に変更;

java -Xmx4g -Xms4g -XX:+UseParallelGC -verbose:gc -cp "./dest/" UseMemoryMain

与える

[GC 1048640K->265430K(4019584K), 0,0902660 secs]

に変更;

java -Xmx4g -Xms4g -XX:+UseConcMarkSweepGC -verbose:gc -cp "./dest/" UseMemoryMain

与える

[GC 1092288K->272230K(3959488K), 0,1791320 secs]

本当に面白いのは、使用する GC メソッドを指定せずに今日再実行すると、これが得られることです。

java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain

与える

[GC 1024064K->259238K(3925376K), 0,0839190 secs]

Java は、何らかの形で GC をデフォルトにするための戦略を変更しました...

4

1 に答える 1

4

ガベージ コレクションは確かにトリッキーなトピックです。最良の回答を得るには、Java の呼び出しに使用される完全なコマンド ラインを投稿する必要があります。

あなたが言ったように、GCスイッチで座礁すると役に立ちます。その理由は、残念ながら、最近使用されている多くのアプリケーションにとってデフォルト設定が最適ではないためです。インタラクティブであるため、高速な応答が必要な多くのアプリケーションでは、パラメータ

-XX:+UseConcMarkSweepGC

大きな違いを生むでしょう。

あなたが言及したJVMを使用し、より大きなヒープ(10GBを超えるとしましょう)を使用するには、常に何らかの調整が必要になることに注意してください。持っている GC ログを取得し、GC オプションを使用したときに動作がどのように変化するかを観察します。さまざまなコレクター戦略 (CMS や G1 など) を試し、Eden Space の構成 (Xmn など) を試してみることをお勧めします。

最後になりましたが、プロファイラーを使用して、アプリケーションがメモリをどのように処理するかを調べることができます。おそらくコードを改善することで、多くの GC を回避できるでしょう。

于 2012-11-25T20:54:20.527 に答える