2012-05-23 44 views
2

问题场景:在sonic MF容器(jvm)中注意到问题。容器托管了一些负责数据库操作和消息转换的java服务。一旦启动,容器运行良好持续2-3周,并自行终止而不会抛出任何例外。如何在JVM自动终止时生成线程转储

经过大量研究,我们无法找出触发jvm(MF Container)关闭的原因或原因。

当jvm自动关闭时,我可以通过哪种方式获得线程转储?我使用的是Java 1.6。有没有其他方法可以解决这个问题?

在此先感谢。

回答

3

你可以尝试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()。但关机挂钩在任何一种情况下工作。因此,即使您也要使用安全管理器或仪器,您应始终使用关闭挂钩。

+0

'有钩子遍历所有线程并转储他们的堆栈跟踪'他应该怎么做? – Cratylus

+0

使用java.lang.Thread.getAllStackTraces()。我会将其添加到我的答案中。 –