我有一个Java程序正在从另一个Java程序通过ProcessBuilder
启动。 System.exit(0)
是从子程序调用的,但对于我们的一些用户(在Windows上),与子项关联的java.exe
进程不会终止。子程序没有关闭挂钩,也没有SecurityManager
可能会阻止System.exit()
终止虚拟机。我无法在Linux或Windows Vista上自己再现问题。到目前为止,这个问题的唯一报告来自两个Windows XP用户和一个Vista用户,使用两个不同的JRE(1.6.0_15和1.6.0_18),但他们每次都能够重现问题。什么会导致Java在System.exit()之后继续运行?
任何人都可以提出的原因为什么JVM将无法在System.exit()
后终止,然后只在某些机器上?
编辑1:我让用户安装JDK,以便我们可以从违规虚拟机获取线程转储。用户告诉我的是,只要点击菜单中的“退出”项,虚拟机进程就会从VisualVM中消失 - 但根据Windows任务管理器的说法,进程并没有终止,无论多长时间用户等待(分钟,小时),它永远不会终止。
编辑2:我已经确认Process.waitFor()
在父程序中永远不会返回至少一个有问题的用户。因此,总结一下:孩子虚拟机似乎已经死了(VisualVM甚至没有看到它),但父母仍然认为该过程是活的,Windows也是这样。
如果它是一个终结,那就不是一个在我们的代码---我们不”没有任何。我确定孩子仍在运行,因为我们看到两个Java进程,并且用户在他的系统上没有任何其他使用Java的程序。我有点希望避免要求他安装JDK,所以我们可以使用jstack,但我认为现在可能是最好的方法。 – uckelman 2010-04-10 21:24:33
我的意思是关于子进程,它是否还有线程?它是否仍然对输入做出反应?它是否仍然有打开的手柄?我比Unix更熟悉Unix,但我知道在Unix操作系统中进程不会被清除,直到父进程收回它们,我认为它在Windows上是一样的。仅仅因为它出现在顶部或TaskManager中并不意味着它仍然活跃。 当然,这并不能解释为什么它只发生在某些用户身上...... – 2010-04-11 01:53:18
默认情况下,终结器不在退出时运行;请参阅http://java.sun.com/javase/6/docs/api/java/lang/System.html#runFinalizersOnExit(boolean) – 2010-04-11 04:01:21