Java线程转储,找不到阻塞其他人的线程

时间:2014-05-06 10:06:23

标签: java multithreading performance thread-dump jstack

我们的申请滞后。

我使用jstack util。

进行线程转储

我做了数据准备并对其进行排序。这就是我所拥有的:

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也有疑问,请查看this question

1 个答案:

答案 0 :(得分: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内在锁的不变属性,只有一个线程可以继续锁定对象,而任意数量的其他线程必须等待。