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>. 你会发现 Thread 锁定了一个对象。然后我查看了堆栈跟踪,最后找到了罪魁祸首。

如果你也有问题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并且大括号中的文本进一步告诉您该对象是Class表示运行时类的实例AccessorInjector

由于此类对象表示声明方法的类,因此该方法可能是一种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)块,那么一切都是合理的。

这是 Java 内在锁的不变属性,只有一个线程可以继续锁定对象,而任意数量的其他线程必须等待。

于 2014-05-13T14:58:54.337 回答