2011-10-28 18 views
7

Sto esaminando un arresto anomalo di JVM che si verifica occasionalmente nella mia applicazione. Il file hs_err contiene i seguenti dettagli sull'arresto anomalo.Che cosa significa BufferBlob :: Interpreter nel registro degli arresti anomali di JVM?

# SIGSEGV (0xb) at pc=0x065e68f4, pid=20208, tid=570166160 
# 
# Java VM: Java HotSpot(TM) Server VM (10.0-b23 mixed mode linux-x86) 

...

# Problematic frame: 
# V [libjvm.so+0x5e68f4] 

...

Current thread (0x099ea800): JavaThread "Thread-315" daemon [_thread_in_vm, id=25782, stack(0x21fa3000,0x21fc1000)] 

...

vm_info: Java HotSpot(TM) Server VM (10.0-b23) for linux-x86 JRE (1.6.0_07-b06), built on Jun 10 2008 01:20:15 by "java_re" with gcc 3.2.1-7a (J2SE release) 

Quindi questo mi dice che la JVM ha colpito un segfault durante l'esecuzione di alcuni Codice Java Il registro degli errori contiene anche informazioni sullo stack del thread che si è arrestato in modo anomalo.

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
V [libjvm.so+0x5e68f4] 
V [libjvm.so+0x1c054f] 
V [libjvm.so+0x1bfef2] 
V [libjvm.so+0x1bf57f] 
V [libjvm.so+0x592495] 
V [libjvm.so+0x365c4e] 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
J org.myapp.AppClass.getBytes()Lorg/myapp/ByteHolder; 

Ho usato GDB per connettersi al file principale dall'arresto anomalo e ottenere maggiori dettagli sullo stack. Questo mi dà il seguente risultato.

#5 <signal handler called> 
#6 0x065e68f4 in interpretedVFrame::monitors() const() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#7 0x061c054f in get_or_compute_monitor_info(JavaThread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#8 0x061bfef2 in revoke_bias(oopDesc*, bool, bool, JavaThread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#9 0x061bf57f in BiasedLocking::revoke_and_rebias(Handle, bool, Thread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#10 0x06592495 in ObjectSynchronizer::fast_enter(Handle, BasicLock*, bool, Thread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#11 0x06365c4e in InterpreterRuntime::monitorenter(JavaThread*, BasicObjectLock*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 

Ciò dimostra che i sei fotogrammi libjvm.so elencati nel bug report originale erano correlati ad afferrare un blocco di Java. Tuttavia, non riesco a trovare alcun codice all'interno di org.myapp.AppClass.getBytes() che utilizza qualsiasi blocco.

Cosa significano le righe di BufferBlob :: Interpreter nello stack? Questi frame stack Java sono? Frame stack JVM? È possibile calcolare ciò che è stato chiamato in questi frame di stack?

NOTA: non suggerire di provare a passare a una JVM Hotspot più recente. Mi affido al raccoglitore CMS e nessuna delle più recenti JVM Hotspot V1.6 è abbastanza stabile con il collector CMS.

MODIFICA: questo documento (http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf) indica che un frame "v" è un "frame stub generato da VM". Qualche idea di cosa significhi?

EDIT2: org.myapp.AppClass.getBytes() legge da un DataInputStream. Ciò può comportare la seguente analisi di stack:

AppClass.getBytes() 
AppClass.readByte() 
DataInputStream.readByte() 
SocketInputStream.read() 
SocketInputStream.read(byte[],int,int) 
PlainSocketImpl.aquireFD() 

questo ultimo metodo afferra una serratura. Questa potrebbe essere la fonte dell'eventuale chiamata nel codice JVM sopra elencato. Questo stack sopra ha la caratteristica chiara che ci sono 5 frame di stack Java sotto getBytes(). Questo corrisponderebbe perfettamente alle 5 linee di BufferBlob :: Interpreter nell'elenco di "Java frames".

Ciò solleva un paio di nuove domande:

  • E 'possibile che le 5 linee di BufferBlob :: Interprete sotto il "frame nativi" sezione sono solo duplicati delle stesse linee sotto le "cornici Java " sezione?
  • Perché il registro degli errori non mostra i dettagli di questi 5 frame stack?

Edit3 - Questo bug Oracle sembra probabile che sia lo stesso/bug simile: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676175

L'analisi dello stack mostrato non è identico, ma si parla di una condizione di competizione rara in revoke_and_rebias, che è stato fissato in 6u14.

edit4 - Il messaggio di taglie dovrebbe dire "familiarità con l'implementazione Hotspot"

risposta

4

VM generated stub frame significa solo che il codice che sta eseguendo è stato generato dalla JVM.

Lo stack stesso (da gdb) indica che la VM sta tentando di raggiungere un safepoint perché sta revocando un blocco di polarizzazione. È possibile leggere il blocco di polarizzazione in this blog. Ciò significa che alcuni thread hanno acquisito un monitor che distorce quel monitor verso quel thread. Successivamente qualche altro thread vuole il lock, quindi deve revocare il bias che richiede il raggiungimento di un safepoint (cioè nessun thread sta eseguendo il codice byte, ovvero ferma il mondo).

Il tuo errore può anche essere indicativo di arresto anomalo della JVM durante la deottimizzazione di alcuni metodi. Ciò significa che la JVM ha già ottimizzato (compilato) determinati metodi, ma poi ha colpito un percorso di codice che ne causa la necessità di deottimizzare perché il metodo compilato non è più valido. È improbabile che trovi una soluzione per questo senza un aggiornamento JVM.

Sembra che avete 2 soluzioni si potrebbe desiderare di provare

  1. se è guidato da blocco di parte, spegnerlo (-XX:-UseBiasedLocking)
  2. se è guidato da deoptimisation, trovare il metodo incriminato e dire hotspot per non compilarlo in primo luogo, le istruzioni su come eseguire questa operazione su this link

Entrambi gli approcci possono avere un impatto sulle prestazioni.

NB questo sarà meno frustrante se è possibile elaborare uno scenario di test che riproduca in modo affidabile il problema.

+0

"significa che il codice che sta eseguendo è stato generato da JVM, cioè codice compilato (ottimizzato)" - La JVM riesce a "org.myapp.AppClass.getBytes()" Nome nonostante fosse un metodo compilato (come per il tag "J"). Talvolta la JVM non è in grado di nominare il metodo che viene eseguito? Oppure le linee "BufferBlob :: Interpreter" si riferiscono a parti di lavoro implicito che la JVM ha inserito nel mio programma? – mchr

+1

Ho modificato quel bit perché non è quello che intendevo dire. Per quanto ne so, un semplice metodo compilato appare ancora come un J. Le linee Interpreter fanno riferimento al codice creato da JVM. La JVM fa un sacco di cose (GC, ottimizzazione) altri eseguono il tuo codice. – Matt

+0

Hmmm ha senso tranne che sono abbastanza sicuro che il mio metodo nello stack (org.myapp.AppClass.getBytes()) non esegue alcun blocco. Ecco perché stavo assumendo che le linee di BufferBlob :: Interpreter dovessero rappresentare ulteriori chiamate di metodo. È possibile? Pensavo che GC e JIT fossero accaduti nelle loro discussioni. – mchr

Problemi correlati