10

正しく動作しない Java VM をデバッグしようとしています。問題のプロセスは、Centos 5 で Sun VM 1.6u24 を実行する大規模な VM (100GB ヒープ) であり、日常的なバックエンド作業 (データベース アクセス、ファイル I/O など) を実行しています。

ソフトウェア バージョンのアップグレードのためにプロセスを再開した後、スループットが大幅に低下していることに気付きました。ほとんどの場合、top は Java プロセスが 2 つのコアを完全に使用していると報告しています。その間、VM はまったく責任を負いません。ログは書き込まれず、jstack や kill -3 などの外部ツールに応答しません。VM が回復すると、プロセスは次のハングまで通常どおり続行されます。

strace は、これらのハングの間、2 つのスレッドだけがシステム コールを行うことを示しています。これらは、VM スレッド「VM Thread」(21776) および「VM Periodic Task Thread」(21786) でした。おそらく、これら 2 つのスレッドが CPU 時間を使い果たしています。アプリケーション スレッドはときどき起動し、作業を行います。残りの時間は、さまざまな futex を待っているようです。ちなみに、正常フェーズの1行目は必ずSIGSEGVです。

[pid 21776] sched_yield()               = 0
[pid 21776] sched_yield()               = 0
[pid 21776] sched_yield( <unfinished ...>
[pid 21786] <... futex resumed> )       = -1 ETIMEDOUT (Connection timed out)
[pid 21776] <... sched_yield resumed> ) = 0
[pid 21786] futex(0x2aabac71ef28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
[pid 21776] sched_yield( <unfinished ...>
[pid 21786] <... futex resumed> )       = 0
[pid 21786] clock_gettime(CLOCK_MONOTONIC, {517080, 280918033}) = 0
[pid 21786] clock_gettime(CLOCK_REALTIME, {1369750039, 794028000}) = 0
[pid 21786] futex(0x2aabb81b94c4, FUTEX_WAIT_PRIVATE, 1, {0, 49923000} <unfinished ...>
[pid 21776] <... sched_yield resumed> ) = 0
[pid 21776] sched_yield()               = 0
[pid 21776] sched_yield()               = 0
[pid 21955] --- SIGSEGV (Segmentation fault) @ 0 (0) ---
[pid 21955] rt_sigreturn(0x2b1cde2f54ad <unfinished ...>

この問題は、2 つの異なるサーバーで発生します。コード バージョンのロールバックは、2 台のサーバーのうちの 1 台でのみ機能しました。システム ログにエラー メッセージは報告されておらず、影響を受けたマシン上の別の Java プロセスは正しく動作しています。

次の出力は gstack で取得されたもので、2 つの典型的な待機中のアプリケーション スレッドを示しています。

Thread 552 (Thread 0x4935f940 (LWP 21906)):
#0  0x00000030b040ae00 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00002b1cdd8548d6 in os::PlatformEvent::park(long) () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#2  0x00002b1cdd92b230 in ObjectMonitor::wait(long, bool, Thread*) () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#3  0x00002b1cdd928853 in ObjectSynchronizer::wait(Handle, long, Thread*) () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#4  0x00002b1cdd69b716 in JVM_MonitorWait () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#5  0x00002b1cde193cc8 in ?? ()
#6  0x00002b1ce2552d90 in ?? ()
#7  0x00002b1cdd84fc23 in os::javaTimeMillis() () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#8  0x00002b1cde188a82 in ?? ()
#9  0x0000000000000000 in ?? ()
Thread 551 (Thread 0x49460940 (LWP 21907)):
#0  0x00000030b040ab99 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00002b1cdd854d6f in Parker::park(bool, long) () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#2  0x00002b1cdd98a1c8 in Unsafe_Park () from /usr/lib/jvm/java/jre/lib/amd64/server/libjvm.so
#3  0x00002b1cde193cc8 in ?? ()
#4  0x000000004945f798 in ?? ()
#5  0x00002b1cde188a82 in ?? ()
#6  0x0000000000000000 in ?? ()

うるう秒のバグを含む NTPD の問題を調査しましたが、提案された回避策は役に立たず、外部 NTPD サーバーの使用も役に立ちませんでした。マシン自体を再起動しても効果はありませんでした。GC ロギングが有効になっていますが、それを示すメッセージがないため、GC の問題ではないようです。この問題に役立つ提案を探しています。どんな助けでも大歓迎です。

4

1 に答える 1

4

ここに私が見たいことがいくつかあります:

  • JVM が応答しない場合は、 と を使用iostatvmstatて、システムがスラッシングしているかどうかを確認します。これは、メモリを過剰に割り当てた場合に発生する可能性があります。つまり、システム全体が物理メモリよりもはるかに多くの仮想メモリを使用しています。

  • JVM の GC ロギングをオンにして、JVM が応答しなくなったことと GC の実行との間に相関関係があるかどうかを確認します。

于 2013-05-28T16:17:03.807 に答える