如何强制Java进程退出热点崩溃

时间:2011-12-19 09:41:15

标签: java windows

如果有热点崩溃,有没有办法确保整个Java进程退出?

我们在远程Windows Java进程(java.exe)中托管本机库,以实现进程隔离。但是,我们发现即使存在热点崩溃,虽然主线程因热点崩溃而“死亡”,但进程本身并不会死亡。我们必须在任务管理器中将其删除。

我们认为这可能是因为本机库本身创建了自己的线程,这使得进程保持活跃状态​​。

如果存在热点崩溃,我们希望整个Java进程死掉。

我们目前的工作是让另一个线程读取生成进程的输出(我们必须先读取控制台输出以阻止进程阻塞)。我们修改它以明确查看VM崩溃:

private static String HOTSPOT_CRASH = "# A fatal error has been detected by the Java Runtime Environment";

public void run() {
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        do {
            line = reader.readLine();
            if (line != null) {
                logger.info(prefix + ": " + line);
            }
            if(line.contains(HOTSPOT_CRASH)) {
                logger.error(String.format("FATAL Hotspot crash detected. Killing child process '%s'...", hostProcess));
                hostProcess.destroy();
            }
        } while (line != null);
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但这是一个黑客行为:如果JVM知道足以注意到崩溃,那么如果可以告诉它终止当前进程会更好。

有没有办法做到这一点?理想情况下,它将是JVM的命令行选项。

1 个答案:

答案 0 :(得分:0)

通常,当检测到致命错误时,VM将退出,但您可以在代码中阻止此操作。以下是一些线索:

  • 检查父进程。在Unix上,子进程只能在父进程处理SIGCHLD信号时(它告诉父进程已终止子进程;这允许父进程读取退出代码)。

    确保您处理输出并在孩子死后至少调用waitFor()一次。这应该清理孩子的过程。

  • 查找非守护程序线程。如果Java应用程序中有任何非守护程序线程,则可以阻止VM退出。

    但VM错误将终止所有线程,所以我猜你永远不会清理子进程。