JVM自动终止时如何生成线程转储

问题场景:在sonic MF容器(jvm)中注意到这个问题。容器托管了一些负责db操作和消息转换的java服务。一旦启动,容器运行正常2-3周并自行终止而不丢弃任何例外。

经过大量研究,我们无法找出导致jvm(MF容器)关闭的原因或原因。

有什么方法可以在jvm自动关闭时获取线程转储? 我正在使用java 1.6。 我应该遵循这个问题的其他方法吗?

提前致谢。

您可以尝试java.lang.Runtime.addShutdownHook() ,并使钩子遍历所有线程并使用Thread.getAllStackTraces()转储其堆栈跟踪。 但是,如果JVM被Runtime.halt()关闭,则不会调用挂钩。 更复杂的是使用检测来挂钩对Runtime.exit()Runtime.halt() (或者Shutdown.sequence()的调用,参见编辑#2),这样你就可以确切地看到当时正在发生的事情。叫做。

编辑 :另一种方法是安装一个SecurityManager ,它不强制执行任何安全性,但是每当调用SecurityManager.checkExit()时都转储线程列表,因为halt()exit()调用该安全管理器方法。 这比使用检测要容易得多,除了记录线程正在执行的操作之外,您甚至可以决定抛出exception。

编辑2 :运行JVM的系统可以告诉JVM终止,在这种情况下使用安全管理器将无法正常工作。 也不会在Runtime.exit()Runtime.halt()上使用检测,因为被调用的方法是java.lang.Shutdown.exit() 。 如果JVM由于最后一个守护程序线程完成而Shutdown.shutdown()则调用Shutdown.shutdown() 。 但是关闭挂钩适用于这两种情况。 因此,即使您还要使用安全管理器或工具,也应始终使用关闭挂钩。

另请参阅https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/hangloop.html “排除悬挂或循环过程故障”

但是,至少在我的情况下,Eclipse是挂起的,并且不响应任何这些。