4

本番サーバーには、ヒープサイズが数ギガバイトのJavaEEアプリケーションがあります。たまに、私たちのサーバーのいずれかがリクエストに反応しなくなります。

  • 問題が発生すると、GCログは、サーバーが8〜10秒かかるGCの実行に多くの/ほとんどの時間を費やしていることを示します(通常は1秒未満かかります)。
  • OutOfMemoryErrorsが発生することはありません。
  • この問題は、ヒープが特定のヒープサイズに達したときに特に発生することはありません。実際、さまざまなヒープサイズで発生し、構成された最大値に近いものはありません。
  • この問題は、特定の間隔、特定の時間、ユーザーの負荷、または特定のサーバーノードでは発生しません。完全にランダムに見えます。
  • ヒープダンプは、問題が表示されている間にサーバーから取得されたものであっても、明らかに間違っているものは何も表示されませんでした。
  • 本番サーバーを毎日再起動すると、問題が発生する可能性が低くなるようですが、修正されません。
  • サーバーを毎日再起動しないと、8台の本番サーバーの1つで1〜3日以内に問題が発生する可能性が高くなります。

これをどのように診断し始めますか?

構成

私たちのJAVA_OPTSは次のとおりです。 -Xms8096m -Xmx8096m -XX:MaxPermSize=512M -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi.dgc.server.gcInterval=1800000 -XX:NewSize=150M -XX:+UseParNewGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/path/to/gc.log

$ java -version
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) 64-Bit Server VM (build 11.2-b01, mixed mode)

$ uname -a
Linux myhostname 2.6.18-274.3.1.el5 #1 SMP Tue Sep 6 20:13:52 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux

$ cat /proc/version
Linux version 2.6.18-274.3.1.el5 (mockbuild@builder10.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-51)) #1 SMP Tue Sep 6 20:13:52 EDT 2011

$ cat /etc/issue
CentOS release 5.7 (Final)
Kernel \r on an \m

$ cat /proc/meminfo|grep "MemTotal"
MemTotal:     16279356 kB

GCログ

これは、問題が発生したときのGCログスニペットの例です。

111036.554: [GC 111036.555: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111036.555: [Tenured: 3629252K->3647971K(5526912K), 8.7565190 secs] 5840068K->3647971K(8014016K), 8.7567840 secs]
111055.691: [GC 111055.691: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111055.691: [Tenured: 3647971K->3667529K(5526912K), 8.7876340 secs] 5858787K->3667529K(8014016K), 8.7878690 secs]
111071.037: [GC 111071.037: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111071.037: [Tenured: 3667529K->3692057K(5526912K), 8.7581830 secs] 5878345K->3692057K(8014016K), 8.7584210 secs]
111088.407: [GC 111088.407: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111088.407: [Tenured: 3692057K->3638194K(5526912K), 10.7072790 secs] 5902873K->3638194K(8014016K), 10.7074960 secs]
111110.238: [GC 111110.238: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111110.238: [Tenured: 3638194K->3654614K(5526912K), 8.8021440 secs] 5849010K->3654614K(8014016K), 8.8023860 secs]
111128.115: [GC 111128.115: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111128.115: [Tenured: 3654614K->3668670K(5526912K), 8.8451510 secs] 5865430K->3668670K(8014016K), 8.8453600 secs]
111161.684: [GC 111161.684: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111161.684: [Tenured: 3668670K->3684080K(5526912K), 8.8156740 secs] 5879486K->3684080K(8014016K), 8.8159260 secs]
111186.669: [GC 111186.669: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111186.669: [Tenured: 3684080K->3639333K(5526912K), 10.6025350 secs] 5894896K->3639333K(8014016K), 10.6030040 secs]
111208.692: [GC 111208.692: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111208.692: [Tenured: 3639333K->3657993K(5526912K), 8.7967920 secs] 5850149K->3657993K(8014016K), 8.7970090 secs]
111235.486: [GC 111235.487: [ParNew: 2210816K->2210816K(2487104K), 0.0000090 secs]111235.487: [Tenured: 3657993K->3676521K(5526912K), 8.8212340 secs] 5868809K->3676521K(8014016K), 8.8214930 secs]
4

3 に答える 3

2

Java の非常に古いバージョン (ほぼ 4 年前) を使用していて、エラー状態になっているように見える場合、最初に試すことは、Java 6 アップデート 35 などの新しいバージョンです。アップデート 12 にはCompressed Oops はデフォルトでオンになっています。これは、メモリを節約するためのオプションです (したがって、オーバーヘッドも節約できます)。

于 2012-11-29T15:10:01.600 に答える
1

まず第一に:スレッドダンプ!プロセスを強制終了 -3 し、ログ出力を確認します。

GC スレッドが実行されていることを確認することで、GC を確認できます。

JVM には 8Go を使用します。RAM は何ギガですか? (少なくとも12であることを願っています)。

スレッド ダンプには、Eden、From、To、Permgen のサイズが表示されます。これは、どのメモリ空間に問題があるかを見つけるのに役立つ場合があります。

于 2012-11-29T15:02:08.900 に答える
0

通常は少し実験が必要ですが、30 分ごとにこの問題が発生していると思いますよね? 満杯の GC がある場合、満杯のヒープが原因ではないように思われる旧世代の行のように、System.gc() が原因である可能性が非常に高くなります。通常、ログでは (System) と出力されますが、VM が古いため、よくわかりません。GC ログ情報は、リリースごとに変更されます。それを解消するには、「-XX:+DisableExplicitGC」を使用することを強くお勧めします。また、DGC が行う呼び出しも無視します。

ここでの 2 番目のオプションは、ダンプに表示されなかったメモリ リーク/問題がある可能性があります。この行は、新しいものには常に 2210816K があり、最後には古いものはまだ 3676521K にあると言っています。2210816K のすべてが生きている場合 (どのように見えるか)、それらを Tenured に移動することは不可能です。これは収まらない (5887337K) ためです。そうしないと、GC オーバーヘッドを超えたというメッセージが表示される可能性があります。ただし、その場合、ダンプを取得したときに、それらの 6G ライブ オブジェクトをヒープに配置する必要があります。

于 2012-11-29T20:16:19.627 に答える