Что означает BufferBlob :: Interpreter в журнале сбоев JVM? - PullRequest
7 голосов
/ 28 октября 2011

Я расследую сбой JVM, который иногда происходит в моем приложении.Файл hs_err содержит следующие сведения о сбое.

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

Итак, это говорит мне о том, что JVM столкнулась с ошибкой при запуске некоторого кода Java.Журнал ошибок также содержит информацию о стеке потока, который аварийно завершился.

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;

Я использовал GDB для подключения к файлу ядра после сбоя и получения более подробной информации о стеке.Это дает мне следующий вывод:

#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

Это показывает, что шесть фреймов libjvm.so, перечисленных в исходном отчете об ошибке, были связаны с захватом блокировки Java.Однако в org.myapp.AppClass.getBytes () я не могу найти код, который использует какие-либо блокировки.

Что означают строки BufferBlob :: Interpreter в стеке?Это фреймы стека Java?Фреймы стека JVM?Можно ли определить, что вызывалось в этих кадрах стека?

ПРИМЕЧАНИЕ. Пожалуйста, не предлагайте мне попробовать перейти на более новую JVM Hotspot.Я полагаюсь на коллектор CMS, и ни одна из более поздних JVM Hotspot V1.6 не является достаточно стабильной с коллектором CMS.

РЕДАКТИРОВАТЬ: В этом документе (http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf) указано, что фрейм "v" является "VM"генерируется заглушка ". Любая идея, что это значит?

EDIT2: org.myapp.AppClass.getBytes () читает из DataInputStream. Это может включать в себя следующую трассировку стека:

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

Этот последний метод захватывает блокировку. Это может быть источником возможного вызова кода JVM, перечисленного выше. Этот стек выше имеет удобную особенность, заключающуюся в том, что под getBytes () есть 5 фреймов стека Java.строки BufferBlob :: Interpreter в списке «Java-фреймов».

Это поднимает пару новых вопросов:

  • Возможно ли, что 5 строк BufferBlob :: Interpreterв разделе «Собственные кадры» просто дубликаты одних и тех же строк в разделе «Кадры Java»?
  • Почему в журнале ошибок не отображаются подробности этих 5 кадров стека?

EDIT3 - эта ошибка Oracle выглядит, вероятно, такой же / похожей ошибкой: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676175

Показанная трассировка стека не идентична, но она упоминает редкое состояние гонки в revoke_and_rebias, котороебыло исправлено в 6u14.

EDIT4 - в сообщении bounty должно быть сказано «знаком с реализацией Hotspot»

Ответы [ 2 ]

4 голосов
/ 28 октября 2011

VM generated stub frame просто означает, что код, который выполняется, был сгенерирован JVM.

Сам стек (из gdb) показывает, что виртуальная машина пытается достичь безопасной точки, потому что она отзывает смещенную блокировку,Вы можете прочитать о предвзятой блокировке в этом блоге .Это означает, что какой-то поток приобрел монитор, который смещает этот монитор к этому потоку.Позже какой-то другой поток хочет блокировку, поэтому он должен отозвать смещение, которое требует достижения безопасной точки (т. Е. Ни один поток не выполняет байт-код, иначе остановите мир).

Ваша ошибка также может указывать на JVMсбой при деоптимизации некоторых методов.Это означает, что JVM уже оптимизировала (скомпилировала) определенные методы, но затем нашла путь к коду, который требует ее деоптимизации, потому что скомпилированный метод больше не действителен.Вам вряд ли удастся найти решение этой проблемы без обновления JVM.

Похоже, у вас есть 2 обходных пути, которые вы, возможно, захотите попробовать

  1. , если он управляется смещенной блокировкой, повернитеотключите его (-XX:-UseBiasedLocking)
  2. , если он вызван деоптимизацией, найдите метод, вызывающий оскорбления, и сначала попросите точку доступа не компилировать ее, инструкции о том, как это сделать на по этой ссылке

Оба подхода могут оказать влияние на производительность.

Обратите внимание, это будет менее неприятно, если вы сможете разработать сценарий тестирования, который надежно воспроизводит проблему.

1 голос
/ 15 ноября 2011

На этот вопрос теперь ответил Том Родригес в списке рассылки hotspot-runtime-dev.

http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2011-November/002592.html

...