Што BufferBlob :: Перакладчык ў часопісе аварыі JVM азначае?

Я расследуе аварыю 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 ударыў Segfault пры запуску некаторых 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  
#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 :: Вусныя радкі ў стэку азначаюць? Ці з'яўляюцца гэтыя кадры стэка Java? JVM стэка кадраў? Ці можна высветліць, што ў цяперашні час называецца ў гэтых кадрах стэка?

Заўвага: Калі ласка, не мяркуе, што я спрабую пераключыцца на больш новую Hotspot JVM. Я спадзяюся на калектар CMS і ні адзін з пазнейшых V1.6 Hotspot JVMs не дастаткова стабільныя з калектарам CMS.

EDIT: Гэта дакумент (http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf) сцвярджае, што «v» кадр з'яўляецца «ВМ генеруецца заглушка кадра». Любая ідэя, што гэта значыць?

EDIT2: org.myapp.AppClass.getBytes() чытае з DataInputStream. Гэта можа ўключаць у сябе наступную трасіроўку стэка:

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

Гэты апошні метад захоплівае замак. Гэта можа быць крыніцай магчымага выкліку ў код віртуальнай машыны Java, пералічаных вышэй. Гэты стэк вышэй, мае акуратную функцыю, што ёсць 5 кадраў стэка Java ніжэй GetBytes (). Гэта будзе адпавядаць акуратна з 5 радкоў BufferBlob :: Перакладчык ў спісе «Java кадраў».

У гэтай сувязі ўзнікае некалькі новых пытанняў:

  • Ці магчыма, што 5 ліній BufferBlob :: інтэрпрэтатарам пад «Родныя кадраў» частка проста дублююць тыя ж радкі ў раздзеле «Java рамкі»?
  • Чаму не часопіс памылак паказваюць дэталі для гэтых 5 кадраў стэка?

EDIT3 - This Oracle bug looks likely to be the same/similar bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676175

Трасіроўкі стэка паказаны не ідэнтычныя, але ён згадвае рэдкае стан гонкі ў revoke_and_rebias, які быў зафіксаваны ў 6u14.

EDIT4 - паведамленне Баунті павінен сказаць, «знаёмыя з рэалізацыяй Hotspot»

7

2 адказы

VM generated stub frame just means that the code that is executing has been generated by the JVM.

Стэк сам (з GDB) паказвае VM спрабуе дасягнуць safepoint, таму што гэта адмяняюць прадузяты замак. Вы можаце прачытаць пра зрушаная блакавання ў гэтага блога . Гэта азначае, што нейкі струмень набыў манітор, які ссоўвае гэты манітор да гэтай тэмы. Пазней іншы паток хоча замак таму ён павінен адмяніць зрушэнне, якое патрабуе safepoint быць дасягнута (гэта значыць ні адзін струмень не выконвае байт-код ака спыніць свет).

Ваша памылка можа таксама паказваць на JVM збой падчас deoptimisation некаторых метадаў. Гэта азначае, што JVM аптымізаваў (укладальнік) некаторыя метады ўжо, але затым ударыў шлях кода, які прымушае яго трэба не deoptimise, таму што скампіляваны метад больш не сапраўдны. Вы наўрад ці знойдзеце выпраўленне для гэтага без абнаўлення віртуальнай машыны Java.

Падобна на тое, у вас ёсць 2 абыходныя шляхі вы можаце паспрабаваць

  1. if it's driven by biased locking, turn it off (-XX:-UseBiasedLocking)
  2. if it's driven by deoptimisation, find the offending method and tell hotspot not to compile it in the first place, instructions on how to do this on this link

Абодва падыходу можа мець уплыў на прадукцыйнасць.

NB гэта будзе менш расчараванняў, калі вы можаце распрацаваць тэставы сцэнар, які надзейна прайгравае праблему.

4
дададзена
«Ці азначае, што код, які выконваецца згенераваны з дапамогай віртуальнай машыны Java, г.зн. скампіляваны (аптымізаваны) код» - Віртуальная машына Java атрымоўваецца назваць «org.myapp.AppClass.getBytes ()», нягледзячы на ​​яго скампіляваны метад (у адпаведнасці з тэгам "J"). Ці з'яўляецца віртуальная машына часам не ў стане назваць метад выконваецца? Або ў «BufferBlob :: Перакладчык» лініі ставяцца да біт няяўнай працы, якую JVM ўставіў у маю праграму?
дададзена аўтар mchr, крыніца
Хммм, што мае сэнс, акрамя таго, што я абсалютна ўпэўнены, што мой метад у стэку (org.myapp.AppClass.getBytes ()) не выконвае ніякай блакавання. Менавіта таму я мяркуючы BufferBlob :: вусных лініі павінны прадстаўляць дадатковыя выклікі метадаў. Ці магчыма гэта? Я думаў, GC і JIT здарылася ў сваіх уласных патоках.
дададзена аўтар mchr, крыніца
Я рэдагаваў гэта крыху, паколькі гэта не тое, што я хацеў сказаць. Просты метад скампіляваны яшчэ выглядае як J, наколькі я ведаю. Лініі перакладчыка зрабіць спасылку на закадаваць JVM стварыла. JVM сапраўды робіць шмат рэчаў (ГЦ, аптымізацыя) іншых запусціць свой код.
дададзена аўтар Matt, крыніца
ёсць некаторая інфармацыя аб тым, як деоптимизации на самай справе адбываецца ў гэтым артыкуле - cs.princeton.edu/ Picasso/кілімкі/HotspotOverview.pdf - а таксама кароткае выклад зрушэння адклікання тут - oracle.com/technetwork/java/javase/tech/… - абодва патрабуюць safepoint, каб быць дасягнута, што азначае фарсіраванне ніткі, каб спыніць. Я думаю, што перакладчык матэрыял ставіцца да інтэрпрэтаванай кадрах, так што, магчыма, перайшоў зваротна з скампіляванага метаду да deoptimized версіі. Я быў бы схільны выкарыстоўваць -XX: + PrintCompilation , каб убачыць, што адбываецца ў некаторых больш падрабязна.
дададзена аўтар Matt, крыніца

Гэтае пытанне цяпер адказаў Том Радрыгес у спісе рассылання гарачая кропка-асяроддзе-Dev.

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

1
дададзена