问题场景:在sonic MF容器(jvm)中注意到这个问题。容器托管了一些负责数据库操作和消息转换的java服务。一旦启动,容器运行正常2-3周并由其终止自己没有任何例外。
经过大量研究,我们无法找出导致jvm(MF容器)关闭的原因或原因。
当jvm自动关闭时,有没有办法让线程转储?我正在使用java 1.6。我应该遵循这个问题的其他方法吗?
提前致谢。
答案 0 :(得分:4)
您可以尝试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终止,在这种情况下使用安全管理器将无法正常工作。也不会在Runtime.exit()
或Runtime.halt()
上使用检测,因为被调用的方法是java.lang.Shutdown.exit()
。如果JVM由于最后一个守护程序线程完成而关闭,则调用Shutdown.shutdown()
。但是关闭钩子将在这两种情况下工作。因此,即使您还要使用安全管理器或工具,也应始终使用关闭挂钩。
答案 1 :(得分:0)
另请参阅https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/hangloop.html"排除挂起或循环过程和#34;
但是,至少在我的情况下,Eclipse是挂起的,并且不响应其中任何一个。