有没有办法确保在Hotspot崩溃时整个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();
}
}
Run Code Online (Sandbox Code Playgroud)
但这是一个黑客攻击:如果JVM知道足以注意到崩溃,那么如果它被告知终止当前进程会好得多.
有没有办法做到这一点?理想情况下,它将是JVM的命令行选项.
通常,当检测到致命错误时,虚拟机将退出,但您可以在代码中阻止这种情况。这里有一些线索:
检查父进程。在 Unix 上,只有当父进程处理信号时,子进程才会死亡SIGCHLD(这告诉父进程子进程已经终止;例如,这允许父进程读取退出代码)。
waitFor()确保处理输出并在孩子死亡后至少调用一次。这应该清理子进程。
寻找非守护线程。如果 Java 应用程序中有任何非守护线程,它们可能会阻止 VM 退出。
但是虚拟机错误会终止所有线程,所以我的猜测是你永远不会清理子进程。
| 归档时间: |
|
| 查看次数: |
642 次 |
| 最近记录: |