7

アプリケーションで時折発生する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)

つまり、これは、Javaコードを実行しているときにJVMがセグメンテーション違反に遭遇したことを示しています。エラーログには、クラッシュしたスレッドのスタックに関する情報も含まれています。

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

これは、元のバグレポートにリストされている6つのlibjvm.soフレームが、Javaロックの取得に関連していることを示しています。ただし、ロックを使用するコードがorg.myapp.AppClass.getBytes()内に見つかりません。

スタック内のBufferBlob::Interpreter行はどういう意味ですか?これらのJavaスタックフレームですか?JVMスタックフレーム?これらのスタックフレームで何が呼ばれていたかを理解することは可能ですか?

注:新しいHotspotJVMに切り替えようとすることを提案しないでください。私はCMSコレクターに依存していますが、最近のV1.6ホットスポットJVMはどれも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スタックフレームがあるという優れた機能があります。これは、「Javaフレーム」のリストにあるBufferBlob::Interpreterの5行とうまく一致します。

これにより、いくつかの新しい質問が発生します。

  • 「ネイティブフレーム」セクションの下のBufferBlob::Interpreterの5行が、「Javaフレーム」セクションの下の同じ行の単なる複製である可能性はありますか?
  • エラーログにこれらの5つのスタックフレームの詳細が表示されないのはなぜですか?

編集3-このOracleのバグは同じ/類似のバグである可能性が高い:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id = 6676175

示されているスタックトレースは同一ではありませんが、6u14で修正されたrevoke_and_rebiasのまれな競合状態について言及しています。

EDIT4-バウンティメッセージには「ホットスポットの実装に精通している」と記載する必要があります

4

2 に答える 2

4

VM generated stub frame実行中のコードがJVMによって生成されたことを意味します。

スタック自体(gdbから)は、バイアスされたロックを取り消しているため、VMがセーフポイントに到達しようとしていることを示しています。このブログでバイアスロックについて読むことができます。これは、一部のスレッドが、そのモニターをそのスレッドにバイアスするモニターを取得したことを意味します。後で他のスレッドがロックを必要とするため、セーフポイントに到達する必要があるバイアスを取り消す必要があります(つまり、バイトコードを実行しているスレッドはありません。

エラーは、一部のメソッドの最適化解除中にJVMがクラッシュしたことを示している場合もあります。これは、JVMが特定のメソッドをすでに最適化(コンパイル)しているが、コンパイルされたメソッドが無効になったために最適化を解除する必要があるコードパスにヒットしたことを意味します。JVMをアップグレードしないと、これに対する修正が見つかる可能性はほとんどありません。

試してみたい2つの回避策があるようです

  1. バイアスロックによって駆動される場合は、オフにします(-XX:-UseBiasedLocking
  2. 最適化解除が原因である場合は、問題のある方法を見つけて、最初からコンパイルしないようにホットスポットに指示します。このリンクでこれを行う方法について説明します。

どちらのアプローチもパフォーマンスに影響を与える可能性があります。

注意:問題を確実に再現するテストシナリオを実行できれば、これはそれほどイライラすることはありません。

于 2011-10-28T13:07:08.697 に答える
1

この質問には、hotspot-runtime-devメーリングリストのTomRodriguezが回答しました。

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

于 2011-11-15T10:35:55.703 に答える