JVM线程转储包含没有锁定线程的监视器

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

Windows 2003上的Java 1.5_14

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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