java - jre - wiki jvm




Que signifie BufferBlob:: Interpreter dans le journal de plantage JVM? (2)

J'étudie un crash JVM qui se produit occasionnellement dans mon application. Le fichier hs_err contient les informations suivantes sur l'incident.

#  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)

Donc, cela me dit que la JVM a frappé un segfault lors de l'exécution du code Java. Le journal des erreurs contient également des informations sur la pile du thread qui s'est écrasé.

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;

J'ai utilisé GDB pour me connecter au fichier core du crash et obtenir plus de détails sur la pile. Cela me donne la sortie suivante.

#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

Cela montre que les six cadres libjvm.so listés dans le rapport de bogue d'origine étaient liés à l'acquisition d'un verrou Java. Cependant, je ne trouve aucun code dans org.monapp.AppClass.getBytes () qui utilise des verrous.

Que signifient les lignes BufferBlob :: Interpreter dans la pile? Sont ces cadres de pile Java? Cadres de pile JVM? Est-il possible de déterminer ce qui était appelé dans ces cadres de pile?

NOTE: S'il vous plaît, ne suggérez pas que j'essaie de passer à une JVM Hotspot plus récente. Je m'appuie sur le collecteur CMS et aucune des JVM V1.6 Hotspot les plus récentes n'est suffisamment stable avec le collecteur CMS.

EDIT: Ce document (http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf) stipule qu'une trame "v" est une "trame de bouchage générée par VM". Une idée de ce que cela signifie?

EDIT2: org.myapp.AppClass.getBytes () lit à partir d'un DataInputStream. Cela pourrait impliquer la trace de pile suivante:

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

Cette dernière méthode saisit un verrou. Cela pourrait être la source de l'appel éventuel dans le code JVM répertorié ci-dessus. Cette pile ci-dessus a la caractéristique intéressante qu'il y a 5 cadres de pile Java sous getBytes (). Cela correspond parfaitement avec les 5 lignes de BufferBlob :: Interpreter dans la liste des "frames Java".

Cela soulève quelques nouvelles questions:

  • Est-il possible que les 5 lignes de BufferBlob :: Interpreter sous la section "Native frames" ne soient que des doublons des mêmes lignes sous la section "frames Java"?
  • Pourquoi le journal des erreurs ne montre-t-il pas les détails de ces 5 cadres de pile?

EDIT3 - Ce bogue Oracle semble être le même / similaire bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676175

La trace de pile montrée n'est pas identique mais elle mentionne une condition de concurrence rare dans revoke_and_rebias qui a été fixée dans 6u14.

EDIT4 - Le message de primes devrait être "familier avec l'implémentation de Hotspot"



VM generated stub frame signifie simplement que le code en cours d'exécution a été généré par la JVM.

La pile elle-même (à partir de gdb) montre que la VM tente d'atteindre un safepoint parce qu'elle révoque un verrou biaisé. Vous pouvez lire sur le verrouillage biaisé dans ce blog . Cela signifie que certains threads ont acquis un moniteur qui polarise ce moniteur vers ce thread. Plus tard, un autre thread veut verrouiller le verrou de sorte qu'il doit révoquer le biais qui nécessite un point de sécurité pour être atteint (c'est-à-dire qu'aucun thread n'exécute de code octet ou arrête le monde).

Votre erreur peut également indiquer que le JVM s'est bloqué lors de la désoptimisation de certaines méthodes. Cela signifie que la JVM a déjà optimisé (compilé) certaines méthodes, mais qu'elle a ensuite frappé un chemin de code qui l'oblige à se désoptimiser car la méthode compilée n'est plus valide. Il est peu probable que vous trouviez un correctif pour cela sans une mise à niveau de la JVM.

Il semble que vous avez 2 solutions de contournement que vous pourriez vouloir essayer

  1. Si le verrouillage est biaisé, désactivez-le ( -XX:-UseBiasedLocking )
  2. si elle est motivée par la désoptimisation, trouvez la méthode incriminée et dites au hotspot de ne pas la compiler en premier lieu, des instructions sur la façon de faire cela sur ce lien

Les deux approches peuvent avoir un impact sur les performances.

NB ceci sera moins frustrant si vous pouvez élaborer un scénario de test reproduisant fidèlement le problème.





jvm-hotspot