背景情報;
サーバー;
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 をデフォルトにするための戦略を変更しました...