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是挂起的,并且不响应任何这些。