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"
"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
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
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