2

私たちのアプリケーションは遅れています。

jstackutilを使用してスレッド ダンプを取得しています。

データの準備と並べ替えを行います。そして、これは私が持っているものです:

198    java.lang.Thread.State: BLOCKED (on object monitor)

198    - waiting to lock <0x0000000582e56bc8> (a java.lang.Class for com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)

198 のスレッドがブロックされています。

からわかるようにwaiting to lock <0x0000000582e56bc8>、それらはすべて ID のスレッドを待っています0x0000000582e56bc8。奇妙なことに0x0000000582e56bc8、スレッド ダンプ出力でこれを見つけることができず、彼らが何を待っているかを見つけることができません。

それとも真実ではありませんか?これは何0x0000000582e56bc8ですか?

ここにダンプの小さな平和があります:

"http-thread-pool-8080(790)" daemon prio=3 tid=0x00000001100fa000 nid=0x339a waiting for monitor entry [0xfffffffeec1f6000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:82)
        - waiting to lock <0x0000000582e56bc8> (a java.lang.Class for com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)

他の 198 個のスレッド ダンプはすべて同じです

更新 1. @Holder コメントの後

"http-thread-pool-8080(642)" daemon prio=3 tid=0x0000000110a8c800 nid=0x32ec runnable [0xffffffff05af5000]
   java.lang.Thread.State: RUNNABLE
        at java.util.zip.Inflater.inflateBytes(Native Method)
        at java.util.zip.Inflater.inflate(Inflater.java:256)
        - locked <0x000000058f2af0c0> (a java.util.zip.ZStreamRef)
        at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:152)
        at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:122)
        at org.apache.felix.framework.util.WeakZipFileFactory$WeakZipFile$WeakZipInputStream.read(WeakZipFileFactory.java:669)
        at java.io.DataInputStream.readShort(DataInputStream.java:312)
        at com.sun.xml.bind.v2.bytecode.ClassTailor.tailor(ClassTailor.java:173)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.tailor(AccessorInjector.java:126)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:85)
        - locked <0x0000000582e56bc8> (a java.lang.Class for com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)
        at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:176)

更新 2 @Holder に感謝

私が理解しているようwaiting to lock <0x0000000582e56bc8>に、 は、スレッドが0x0000000582e56bc8ポインタである を待っていることを意味します。次に、 を見つける必要があります- locked <0x0000000582e56bc8>。そして、オブジェクトをロックしたスレッドが見つかります。それからスタックトレースを見て、最後に犯人を見つけました。

にも問題がある場合は、この質問com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjectorを見てください。

4

1 に答える 1

2

質問のコメントで行われたように、スタックトレースを読んで問題を見つける方法を要約するには:

次のようなエントリを見つけた場合

  at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:82)
  - waiting to lock <0x0000000582e56bc8> (a java.lang.Class for com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)

スタック トレース内では、スレッドが番号で表されるオブジェクト インスタンスをロックしようとしていることがわかり、中かっこ内のテキストは、このオブジェクトがランタイム クラスを表すインスタンス0x0000000582e56bc8であることをさらに伝えます。ClassAccessorInjector

このクラス オブジェクトはメソッドを宣言しているクラスを表すため、メソッドがメソッドである可能性static synchronizedがありますが、メソッドに のような構造が含まれている可能性もありますsynchronized(AccessorInjector.class)

- lockedそのため、スタック トレースに一致するエントリが含まれているスレッドを見つけて、どのスレッドが他のスレッドをブロックしているかを知る必要があります。

一致を見つけたので

  at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:85)
  - locked <0x0000000582e56bc8> (a java.lang.Class for com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)

オブジェクトをロックしたスレッドが待機中のスレッドと同じメソッドを実行していることがわかるので、このメソッドがブロックであるsynchronizedかブロックを含んでいる場合、すべてが妥当であることがわかりsynchronized(AccessorInjector.class)ます。

任意の数の他のスレッドが待機しなければならない間、1 つのスレッドのみがオブジェクトをロックした状態で続行できるというのは、Java の組み込みロックの不変のプロパティです。

于 2014-05-13T14:58:54.337 に答える