2013-05-28 18 views
8

Tentativo di eseguire il debug di una Java VM anomala. Il processo in questione è una grande VM (heap da 100 GB) che esegue Sun VM 1.6u24 su CentOS 5 che sta eseguendo un lavoro di back-end di routine, ad esempio accesso al database, I/O di file e così via.JVM si blocca periodicamente

Dopo il riavvio del processo per un aggiornamento della versione del software, abbiamo notato che il suo throughput è notevolmente diminuito. Nella maggior parte dei casi, i principali rapporti sul processo Java stanno utilizzando completamente 2 core. Durante questo periodo, la VM è totalmente non responsabile: non vengono scritti registri e non risponde a strumenti esterni come jstack o kill -3. Una volta ripristinata la VM, il processo continua normalmente, fino al prossimo blocco.

strace indica che durante questi blocchi, solo 2 thread effettuano chiamate di sistema. Questi erano i thread VM "VM Thread" (21776) e "VM Periodic Task Thread" (21786). Presumibilmente, questi 2 thread stanno utilizzando il tempo della CPU. I thread dell'applicazione si attivano occasionalmente e si attivano. Il resto del tempo sembra che stiano aspettando vari futures. Per inciso, la prima riga della fase normale è sempre un 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 ...> 

Il problema si manifesta in 2 server diversi. Il rollback della nostra versione del codice ha funzionato solo per uno dei 2 server. Nessun messaggio di errore è stato segnalato nei log di sistema e un altro processo Java sul computer interessato si sta comportando correttamente.

Questo seguente risultato è stato ottenuto con gstack e spettacoli 2 tipici thread delle applicazioni di attesa:

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 ??() 

abbiamo guardato problemi con NTPD, tra cui secondo intercalare bug, ma le soluzioni alternative suggerite non ha aiutato, nemmeno utilizzando server NTPD esterni. Anche il riavvio della macchina non è stato di aiuto. Abbiamo abilitato la registrazione GC e non sembra un problema di GC, in quanto non ci sono messaggi che lo indicano. Alla ricerca di eventuali suggerimenti che possono aiutare con questo problema, ogni aiuto è molto apprezzato.

+1

Potrebbe essere "pausa GC"? hai controllato l'algoritmo GC usato? http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#0.0.0.%20The%20Concurrent%20Low%20Pause%20Collector%7Coutline – kosa

+0

Sono d'accordo con @Nambari - I have ho visto pause molto lunghe in JVM di grandi dimensioni quando sono sotto carico. Se il processo GC non può essere completato in un intervallo di tempo ragionevole, è possibile che si verifichi un errore di memoria insufficiente. Il tuo JVM ha davvero bisogno di essere così grande? –

+0

Più grande è l'heap, più oggetti devono essere risolti dal processo GC –

risposta

3

Qui ci sono un paio di cose che mi piacerebbe guardare:

  • Quando la JVM non risponde, utilizzare iostat e vmstat per vedere se il sistema è santa ragione. Questo può accadere quando si sovrascrive la memoria; Ad esempio, il tuo sistema generale utilizza molta più memoria virtuale della memoria fisica.

  • attiva la registrazione GC della JVM, e vedere se esiste una correlazione tra la JVM andare risponde e GC corre.