2013-05-28 29 views
8

Der Versuch, eine fehlgeschlagene Java VM zu debuggen. Bei dem fraglichen Prozess handelt es sich um eine große VM (100 GB-Heap), auf der Sun VM 1.6u24 auf Centos 5 ausgeführt wird, die routinemäßige Back-End-Aufgaben ausführt - z. B. Datenbankzugriff, Datei-E/A usw.JVM hängt in regelmäßigen Abständen

Nachdem der Prozess für eine Softwareversionsaktualisierung neu gestartet wurde, haben wir festgestellt, dass der Durchsatz erheblich gesunken ist. Die meiste Zeit berichtet top, dass der Java-Prozess 2 Kerne vollständig nutzt. Während dieser Zeit ist die VM völlig unverantwortlich: Es werden keine Protokolle geschrieben, und sie reagiert nicht auf externe Tools wie jstack oder kill -3. Sobald die VM wiederhergestellt ist, wird der Prozess normal fortgesetzt, bis zum nächsten Hang.

strace zeigt, dass während dieser Hänge nur 2 Threads Systemaufrufe tätigen. Dies waren die VM-Threads "VM Thread" (21776) und "VM Periodic Task Thread" (21786). Vermutlich verbrauchen diese 2 Threads die CPU-Zeit. Die Anwendungs-Threads wachen gelegentlich auf und erledigen ihre Arbeit. Der Rest der Zeit scheinen sie auf verschiedene Futexes zu warten. Übrigens ist die erste Zeile der normalen Phase immer ein 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 ...> 

Das Problem manifestiert sich in 2 verschiedenen Servern. Rollback unserer Code-Version funktionierte nur für einen der 2 Server. In Systemprotokollen wurden keine Fehlermeldungen gemeldet, und ein anderer Java-Prozess auf der betroffenen Maschine verhält sich ordnungsgemäß.

Die folgende Ausgabe wurde mit gstack erhalten und zeigt zwei typische Warteanwendungsthreads:

Thread 552 (Thread 0x4935f940 (LWP 21906)): 
#0 0x00000030b040ae00 in [email protected]@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 [email protected]@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 ??() 

Wir sahen Probleme mit NTPD, einschließlich Sprung zweiter Fehler, aber die vorgeschlagenen Abhilfen nicht helfen, auch nicht mit externe NTPD-Server. Der Neustart der Maschine selbst hat auch nicht geholfen. Wir haben die GC-Protokollierung aktiviert und es sieht nicht wie ein GC-Problem aus, da keine Nachrichten darauf hinweisen. Auf der Suche nach Vorschlägen, die mit diesem Problem helfen können, wird jede Hilfe sehr geschätzt.

+1

Könnte es sein, dass "GC pause"? Haben Sie den verwendeten GC-Algorithmus überprüft? http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#0.0.0.%20The%20Concurrent%20Low%20Pause%20Collector%7Coutline – kosa

+0

Ich stimme @Nambari - ich habe sehr lange Pausen in großen JVMs gesehen, wenn sie unter Last sind. Wenn der GC-Prozess nicht in einem vernünftigen Zeitrahmen abgeschlossen werden kann, erhalten Sie möglicherweise einen Fehler wegen zu wenig Arbeitsspeicher. Muss deine JVM wirklich so groß sein? –

+0

Je größer der Heap, desto mehr Objekte müssen vom GC-Prozess aufgelöst werden. –

Antwort

3

Hier sind ein paar Dinge, die ich betrachten würde:

  • Wenn die JVM ist nicht mehr reagiert, iostat und vmstat verwenden, um zu sehen, ob das System Dreschen ist. Dies kann passieren, wenn Sie Speicher zu viel Speicherplatz zuweisen; Ihr gesamtes System verwendet wesentlich mehr virtuellen Speicher als physischer Speicher.

  • Schalten Sie die GC-Protokollierung der JVM ein, und prüfen Sie, ob eine Korrelation zwischen der nicht reagierenden JVM und der GC-Ausführung besteht.