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

4
问题场景:在Sonic MF容器(jvm)中发现了问题。该容器托管了一些负责数据库操作和消息转换的Java服务。一旦启动,容器在2-3周内运行良好,并且在没有抛出任何异常的情况下自动终止。
经过多次研究,我们无法找出JVM(MF容器)为什么或者是什么触发了它关闭的原因。
有没有办法在JVM自动关闭时获取线程转储?我正在使用Java 1.6。是否有其他应对这个问题的方法?
提前感谢。
2个回答

5
您可以尝试使用java.lang.Runtime.addShutdownHook(),并让挂钩迭代所有线程,并使用Thread.getAllStackTraces()转储它们的堆栈跟踪。但是,如果JVM由Runtime.halt()关闭,则不会调用挂钩。更复杂的方法是使用instrumentation来钩住对Runtime.exit()Runtime.halt()(或Shutdown.sequence(),请参见编辑#2)的调用,以便您可以在调用任何一个时看到确切发生了什么。 编辑:另一种方法是安装一个SecurityManager,它不执行任何安全性检查,但在调用halt()exit()时转储线程列表,因为这两个方法都调用该安全管理器方法。这比使用instrumentation要容易得多,您甚至可以决定除记录线程正在执行的操作外,还要抛出异常。 编辑2:运行JVM的系统可以告诉JVM终止,这种情况下使用安全管理器将不起作用。对Runtime.exit()Runtime.halt()进行检测也不会起作用,因为被调用的方法是java.lang.Shutdown.exit()。如果JVM正在关闭,因为最后一个守护线程完成,则会调用Shutdown.shutdown()。但是,在任何这些情况下,都可以使用关闭挂钩。因此,即使您还要使用安全管理器或instrumentation,也应始终使用关闭挂钩。

让钩子迭代所有线程并转储它们的堆栈跟踪。他应该怎么做? - Cratylus
使用java.lang.Thread.getAllStackTraces()。我会将其添加到我的答案中。 - Matthew Cline

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接