包含监视器但未锁定线程的JVM线程转储

时间:2020-03-05 18:54:04  来源:igfitidea点击:

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

Windows 2003上的Java 1.5_14

解决方案

回答

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

回答

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

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

回答

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

我们已经看到了类似的行为,但是JDK 1.6.0_05. App似乎死锁,但是Jstack显示了线程正在等待没有其他线程持有的锁。我们有一些JNI代码,因此有可能我们正在破坏某些内容。

我们尚未找到解决方案,该问题只能在1台计算机上重现。

回答

这些等待线程是否一直在等待,或者它们最终会继续进行?

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

我们可以在Java命令行上添加带有-XX:+ PrintGCDetails的参数-verbose:gc与-XX:+ PrintGCDetails,以告知何时发生GC。如果gc活动与速度下降同时发生,则可能表明这是问题所在。

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

回答

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

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

此处的主要观察结果是,类加载器的锁未在线程转储中显示为已锁定。

完整答案可以在此线程上找到。

回答

我们是否尝试过升级到Java 1.6?如果我们仅使用1.5,则可能是个问题。