8

JVM 线程转储显示线程等待锁定在监视器上的原因可能是什么,但监视器没有相应的锁定线程?

Windows 2003 上的 Java 1.5_14

4

6 回答 6

1

您的代码是否通过任何更改使用任何 JNI?(即,您是否正在运行从 Java 启动的任何本机代码?)。

我们已经看到了类似的行为,但是 JDK 1.6.0_05。应用程序似乎死锁,但 Jstack 显示线程正在等待没有其他线程持有的锁。我们有一些 JNI 代码,所以我们可能正在破坏某些东西。

我们还没有找到解决方案,这个问题只能在一台机器上重现。

于 2008-09-17T03:15:56.657 回答
1

那些等待的线程是永远等待,还是最终会继续?

如果是后者,则可能是垃圾收集器持有该锁。

您可以在您的 java 命令行上添加参数-verbose:gc with -XX:+PrintGCDetails,以便在 GC 发生时被告知。如果 gc 活动与您的减速一致,则可能表明这是问题所在。

这是有关垃圾收集的一些信息。

于 2008-09-17T03:31:35.433 回答
0

是的,通常每个被锁定的监视器都必须有一个所有者线程。也许您的堆栈转储不完整(太长)或者转储不一致。我可以想象它并没有停止世界,所以一个锁定的监视器被转储但拥有锁的线程在被转储之前释放它(这只是一个猜测)。

您能否将转储上传为文本文件以便于搜索,并告诉我们您正在查看哪个监视器。

于 2008-09-16T18:47:22.057 回答
0

这只是一个疯狂的猜测,但有没有可能是线程通过尝试两次获取锁来锁定自己?如果您可以发布一些代码,可能会有所帮助。

于 2008-09-15T18:33:29.400 回答
0

我今天也遇到了类似的问题,也涉及到静态资源的访问。

简短的版本是一个类在静态块中进行了 GUI 更改,并且在 AWT-EventQueue 线程之外,被 AWT TreeLock 阻塞,然后 EventQueue 引用了被阻塞的类,这迫使它等待该类的类加载器的监视器。

这里的关键观察是类加载器的锁在线程转储中没有显示为锁定。

完整的答案可以在这个线程上找到。

于 2010-09-16T16:47:28.200 回答
0

您是否尝试过升级到 Java 1.6?如果您仅使用 1.5,则错误可能是您的问题。

于 2010-09-16T16:49:08.863 回答