问题场景:在sonic MF容器(jvm)中注意到问题。容器托管了一些负责数据库操作和消息转换的java服务。一旦启动,容器运行良好持续2-3周,并自行终止而不会抛出任何例外。如何在JVM自动终止时生成线程转储
经过大量研究,我们无法找出触发jvm(MF Container)关闭的原因或原因。
当jvm自动关闭时,我可以通过哪种方式获得线程转储?我使用的是Java 1.6。有没有其他方法可以解决这个问题?
在此先感谢。
问题场景:在sonic MF容器(jvm)中注意到问题。容器托管了一些负责数据库操作和消息转换的java服务。一旦启动,容器运行良好持续2-3周,并自行终止而不会抛出任何例外。如何在JVM自动终止时生成线程转储
经过大量研究,我们无法找出触发jvm(MF Container)关闭的原因或原因。
当jvm自动关闭时,我可以通过哪种方式获得线程转储?我使用的是Java 1.6。有没有其他方法可以解决这个问题?
在此先感谢。
你可以尝试java.lang.Runtime.addShutdownHook(),并让钩子迭代所有线程并将其堆栈跟踪转储为Thread.getAllStackTraces()。但是,如果JVM被关闭了Runtime.halt()
那么钩子将不会被调用。更复杂的是,使用instrumentation挂接到Runtime.exit()
和Runtime.halt()
(或Shutdown.sequence()
,请参阅编辑#2)的调用,以便您可以在调用任何时间时看到发生了什么。
编辑:这样做会安装一个SecurityManager不执行任何安全性的另一种方式,但它转储线程列表时SecurityManager.checkExit()
,因为这两个halt()
和exit()
调用安全管理方法。这将比使用检测更容易,除了记录线程正在做什么之外,您甚至可以决定抛出异常。
编辑2:运行JVM的系统可以告诉JVM终止,在这种情况下使用安全管理器将不起作用。由于被调用的方法是java.lang.Shutdown.exit()
,所以也不会在Runtime.exit()
或Runtime.halt()
上使用仪器。如果JVM由于最后的守护进程线程完成而关闭,则调用Shutdown.shutdown()
。但关机挂钩将在任何一种情况下工作。因此,即使您也要使用安全管理器或仪器,您应始终使用关闭挂钩。
参见https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/hangloop.html“故障排除悬挂或循环过程”
然而,至少在我的情况下,Eclipse是挂,并且不以任何的这些做出响应。
'有钩子遍历所有线程并转储他们的堆栈跟踪'他应该怎么做? – Cratylus
使用java.lang.Thread.getAllStackTraces()。我会将其添加到我的答案中。 –