Java 线程转储:阻塞线程没有“等待锁定...”
我很难理解从 jstack 获得的 Tomcat 6(java 1.6.0_22,Linux)上运行的 Spring MVC Web 应用程序的线程转储。
我看到阻塞线程(导致其他线程等待)本身被阻塞,但是线程转储并没有告诉我原因或它们正在等待哪个监视器。
示例:
"TP-Processor75" daemon prio=10 tid=0x00007f3e88448800 nid=0x56f5 waiting for monitor entry [0x00000000472bc000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Class.initAnnotationsIfNecessary(Class.java:3067)
- locked <0x00007f3e9a0b3830> (a java.lang.Class for org.catapultframework.resource.ResourceObject)
at java.lang.Class.getAnnotation(Class.java:3029)
...
即我在堆栈跟踪中缺少“等待锁定...”行。显然线程锁定了一个 Class 对象,但我不明白为什么线程本身被阻塞。
线程转储不包含任何死锁提示。
我可以做什么来识别锁定监视器?
谢谢, 奥利弗
I'm having difficulties in understanding the thread dump I got from jstack for a Spring MVC web application running on Tomcat 6 (java 1.6.0_22, Linux).
I see blocking threads (that cause other threads to wait) which are blocked themselves, however the thread dump doesn't tell me why or for which monitor they are waiting.
Example:
"TP-Processor75" daemon prio=10 tid=0x00007f3e88448800 nid=0x56f5 waiting for monitor entry [0x00000000472bc000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Class.initAnnotationsIfNecessary(Class.java:3067)
- locked <0x00007f3e9a0b3830> (a java.lang.Class for org.catapultframework.resource.ResourceObject)
at java.lang.Class.getAnnotation(Class.java:3029)
...
I.e. I am missing the "waiting to lock ..." line in the stack trace. Apparently the thread locks a Class object, but I don't see why the thread itself is blocked.
The thread-dump does not contain any hints for deadlocks.
What can I do to identify the locking monitor?
Thanks,
Oliver
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
显然,我们观察到的此类阻塞线程的情况与大量内存消耗以及因此产生的大量垃圾收集有关。
这个问题Java阻塞问题:为什么 JVM 会阻塞许多不同类/方法中的线程? 描述了类似的情况,所以我相信这些线程只是被垃圾收集器阻塞了。
(无论如何,解决内存问题后,阻塞线程的问题就消失了。)
Apparently the situation where we observed these kinds of blocked threads were related to heavy memory consumption and therefore massive garbage collection.
This question Java blocking issue: Why would JVM block threads in many different classes/methods? describes a similar situation, so I believe these threads were simply blocked by the garbage collector.
(Anyway, after solving the memory issue this problem with the blocking threads was gone.)
检查终结器线程是否被阻塞或等待。
在GC扫描期间,GC将“停止世界”以执行其清理。 “世界”的定义取决于所使用的垃圾收集器和上下文。它可能是一小群线程或所有线程。在正式收集垃圾之前,GC会调用对象的finalize()。
如果您处于实现终结器方法的不良情况,则终结代码可能会阻止它完成,并且“世界”保持停止状态。
当看到大量线程被某种未知的魔力永久阻塞时,这一点最为明显:查找发生阻塞的代码,它毫无意义;在它附近的任何地方都找不到阻塞代码,并且转储不会泄露它正在等待哪个监视器,因为没有监视器。 GC 已暂停线程。
Check if the finalizer thread is blocked or waiting.
During a GC sweep, the GC will "stop the world" to perform its cleanup. The definition of "world" depends on the garbage collector being used and context. It may be a small cluster of threads or all of them. Before officially collecting garbage, GC will invoke the object's finalize().
If you are in the undesirable situation where you are implementing finalizer methods, the finalization code may be blocking it from finishing and the 'world' stays stopped.
This is most obvious when seeing lots of threads being permanently-blocked by some unknown magic force: Look up the code where the blocking occurs and it will make no sense; there is no blocking code to be found anywhere near it and the dumps will not divulge what monitor it is waiting on because there isn't one. The GC has paused the threads.
我刚刚在 Google Chrome 中使用 Applet 时遇到了类似的问题。
简而言之:
详细信息:
我有以下场景:
new Runnable() ...
的Executor
来分离调用,以减少等待时间,从而在 JS 中挂起。说明:
new Runnable()
是一个匿名内部类,在 JS 调用发生之前尚未加载。这是尝试加载类的被阻止的线程:
正如您所看到的,它正在等待消息 -->
waitForMessage()
。同时,我们传入的 JS 调用在这里被阻止:
其他其他线程以相同的方式被阻止。我想所有后续的类加载请求都被第一个被阻止的类加载线程阻止。
如前所述,我的猜测是类加载过程被待处理的 JS 调用阻塞,而该调用本身又被缺少的要加载的类阻塞。
解决方案:
。
I had a similar problem just now using an Applet in Google Chrome.
In short:
In Detail:
I had the following scenario:
Executor
withnew Runnable() ...
to detach the calls in order to reduce the wait times and thus hangs in JS.Explanation:
new Runnable()
is an annonymous inner class which was not loaded before the JS call happened.Here is the blocked thread that is trying to load the class:
As you can see it is waiting for a message -->
waitForMessage()
.At the same time there is our incoming JS call being BLOCKED here:
Additional other threads were blocked in the same manner. I suppose all subsequent class-load requests were blocked by the first blocked class-loading thread.
As mentioned before, my guess is that the class-loading process is blocked by the pending JS call, which by itself is blocked by the missing class to be loaded.
Solutions:
My implementation for #3:
这是 Oracle HotSpot JVM 中的一个外观错误 - 在堆栈跟踪中,您会看到
-locked <0x00007f3e9a0b3830>
,它实际上应该显示- waiting to lock <0x00007f3e9a0b3830>
。有关更多详细信息,请参阅此错误。
This is a cosmetic bug in Oracle's HotSpot JVM - in your stack trace where you see
- locked <0x00007f3e9a0b3830>
it should actually say- waiting to lock <0x00007f3e9a0b3830>
.See this bug for more details.