我在使用JDK 1.5.0_08的Fedora Core 6上运行应用程序时遇到问题。
经过一段时间(通常是几天)后,线程开始陷入原生方法。
线程被锁定在这样的东西:
"pool-2-thread-2571" prio=1 tid=0x08dd0b28 nid=0x319e waiting for monitor entry [0xb91fe000..0xb91ff7d4]
at java.lang.Class.getDeclaredConstructors0(Native Method)
或
"pool-2-thread-2547" prio=1 tid=0x75641620 nid=0x1745 waiting for monitor entry [0xbc7fe000..0xbc7ff554]
at sun.misc.Unsafe.defineClass(Native Method)
特别令我困惑的是这个:
"HealthMonitor-10" daemon prio=1 tid=0x0868d1c0 nid=0x2b72 waiting for monitor entry [0xbe5ff000..0xbe5ff4d4]
at java.lang.Thread.dumpThreads(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:1383)
在VM重新启动之前,线程一直处于停滞状态。
任何人都可以告诉我这里发生了什么,可能导致本机方法阻塞的原因是什么? 每个卡住线程顶部的监视器入口地址范围不同。我怎么能弄清楚拿着这台显示器的是什么?
非常感谢任何建议或建议!
谢谢, 大卫
答案 0 :(得分:4)
我最初的怀疑是你正在经历某种类加载器实现的死锁。我想,类加载需要在某个级别进行同步,因为类信息将可用于整个VM,而不仅仅是最初加载它的线程。
堆栈顶部的方法是本机方法的事实似乎是纯粹的巧合,因为类加载机制的一部分碰巧以这种方式实现。
我会进一步调查类加载的内容。也许某些线程使用类加载器从一个缓慢/不可用的网络位置加载一个类,因此阻塞很长时间,而不是让监视器到其他想要加载类的线程。使用-verbose:class启动JVM时调查输出可能是一回事。
答案 1 :(得分:2)
从jthread的输出中,我可以看到一个线程在进入监视器后尝试获取锁定,另一个线程在获取锁定后尝试进入监视器。僵局的秘诀。
我还想知道你的应用程序是否遇到了垃圾收集问题。你说它在它停止之前运行了几天。你有多久让它处于卡住状态,看看GC是否能完成?
答案 2 :(得分:1)
你能找出在本机方法等待的监视器上实际正在同步的线程吗? 至少你发送一个SIGQUIT(kill -3)时从VM获得的线程转储应该显示这个信息,如
"Thread-0" prio=5 tid=0x0100b060 nid=0x84c000 waiting for monitor entry [0xb0c8a000..0xb0c8ad90]
at Deadlock$1.run(Deadlock.java:8)
- waiting to lock <0x255e5b38> (a java.lang.Object)
...
"main" prio=5 tid=0x01001350 nid=0xb0801000 waiting on condition [0xb07ff000..0xb0800148]
at java.lang.Thread.sleep(Native Method)
at Deadlock.main(Deadlock.java:21)
- locked <0x255e5b38> (a java.lang.Object)
在目前为止发布的转储中,我看不到任何实际等待锁定特定监视器的线程......
答案 3 :(得分:0)
也许你应该使用另一个jdk版本
对于你的“令人费解的”,有一个1.5.0_08的错误条目。报告内存泄漏(我不知道,如果这与您的问题有关):
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6469701
此外,您可以获取源代码并查看,第1383行会发生什么。另一方面,它可能只是原始错误发生后的堆栈转储。
答案 4 :(得分:0)
我在遇到同样的问题后找到了这个线程 - 在Linux上使用Tomcat 6.0.29运行JDK 1.6.0_23。但是不确定这些位是否相关 - 我注意到的是,除了许多线程在getDeclaredConstructors()本机方法中“卡住”之外,java进程的CPU为100%。因此,所有请求线程都被卡在这里,CPU处于100%,线程转储没有显示任何死锁(并且没有其他线程执行任何重要活动),它闻起来像一个颠簸的垃圾收集器给我。果然,检查了服务器日志,并且出现了大量的OutOfMemory错误 - 堆空间已经耗尽。
不能说这会是线程每次都卡在这里的根本原因,但希望这里的信息能帮助其他人至少排除这个可能的原因......