I have a Java program which is being started via ProcessBuilder
from another Java program. System.exit(0)
is called from the child program, but for some of our users (on Windows) the java.exe
process associated with the child doesn't terminate. The child program has no shutdown hooks, nor does it have a SecurityManager
which might stop System.exit()
from terminating the VM. I can't reproduce the problem myself on Linux or Windows Vista. So far, the only reports of the problem come from two Windows XP users and one Vista user, using two different JREs (1.6.0_15 and 1.6.0_18), but they're able to reproduce the problem every time.
Can anyone suggest reasons why the JVM would fail to terminate after System.exit()
, and then only on some machines?
Edit 1: I got the user to install the JDK so we could get a thread dump from the offending VM. What the user told me is that the VM process disappears from VisualVM as soon as he clicks on the 'Quit' item in my menu---but, according to Windows Task Manager, the process hasn't terminated, and no matter how long the user waits (minutes, hours), it never terminates.
Edit 2: I have confirmed now that Process.waitFor()
in the parent program never returns for at least one of the users having the problem. So, to summarize: The child VM seems to be dead (VisualVM doesn't even see it) but the parent still sees the process as live and so does Windows.
To end a Java program, we can use the exit() method of the System class. It is the most popular way to end a program in Java. System. exit() terminates the Java Virtual Machine(JVM) that exits the current program that we are running.
System. exit() method. This method terminates the currently running Java Virtual Machine(JVM). It takes an argument “status code” where a non zero status code indicates abnormal termination.
The main alternative is Runtime. getRuntime(). halt(0) , described as "Forcibly terminates the currently running Java virtual machine". This does not call shutdown hooks or exit finalizers, it just exits.
Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java. If we call the System. exit() method explicitly in the finally block then only it will not be executed.
This can happen if your code (or a library you use) has a shutdown hook or a finalizer that doesn't finish cleanly.
A more vigorous (so should only be used in extreme cases!) way to force shutdown is by running:
Runtime.getRuntime().halt(0);
The parent process has one thread dedicated to consuming each of the child's STDOUT and STDERR (which passes that output through to a log file). So far as I can see, those are working properly, since we're seeing all the output we expect to see in the log
i had a similar problem with my program not disappearing from task mgr when i was consuming the stdout/stderr. in my case, if I closed the stream that was listening before calling system.exit() then the javaw.exe hung around. strange, it wasn't writing to the stream...
the solution in my case was to simply flush the stream rather than close it before existing. of course, you could always flush and then redirect back to stdout and stderr before exit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With