我使用org.jruby.embed.ScriptingContainer
API在JVM进程内运行JRuby上的Middleman(使用Webrick)服务器。
如果我干净地关闭并从JVM内部停止服务器,一切都按预期工作。
但是如果我将一个SIGTERM发送到JVM进程(例如,通过在命令行中按ctrl + C),控制台将返回但JVM进程不会终止 - 它会无限期地挂起,直到我发送一个SIGKILL。
我尝试注册JVM关闭挂钩来终止ScriptingContainer
实例,但挂钩永远不会触发。我不知道为什么......也许JRuby不知怎的吞下了SIGTERM?
即使JVM包含正在运行的Webrick服务器,如何让JVM完全关闭呢?
答案 0 :(得分:1)
看起来kill -9
不会触发shutdownHook,但kill -15
会触发。{/ p>
This StackOverflow question对同一问题有详细解答。
底线是,你搞砸了,因为在JVM停止之前似乎没有任何方法可以拦截kill -9
信号并执行一些维护任务。
答案 1 :(得分:0)
首先,一个调试技巧:您可以将SIGQUIT
发送到Java进程,以使其打印所有正在运行的线程的当前堆栈跟踪。这可以帮助您诊断哪些线程导致JVM无法退出。
发送SIGINT
,SIGHUP
或SIGTERM
会导致Java运行其关闭挂钩,然后退出。您可以在java.lang.Terminator
中看到此信息。收到信号后,java.lang.Shutdown
会在终止进程之前处理所有关闭挂钩的运行。在关闭钩子全部完成之后才会调用Shutdown.halt()
,这表示你有一个挂起的关闭钩子。
如果没有实际的代码或堆栈跟踪,很难提供比这更精确的答案,但是在发送SIGINT
之后保持活跃的JVM通常会在其关闭挂钩中做一些奇怪的事情。如果这还不够,请尝试发送SIGINT
,等待几秒钟,然后发送SIGQUIT
,并将结果堆栈跟踪添加到问题中。