I have a simple test run of some medium-complexity code that won't terminate, i.e. the main method finishes but the process does not die.
Here is a rundown of the code (which is too long to be pasted here):
ProcessBuilder
is used to create a bunch of subprocesses. They all die properly (if you can believe VisualVM).FutureTask
on which run
and later get
are called.Obviously, I can call System.exit(0)
, but I'd like to know what is amiss here. I have not been able to produce a minimum failing example. Also, I can not identify an obvious culprit from the thread list; maybe you can?
Edit: See here for a thread dump.
If you simply close the window, it usually is only hidden, and the EDT still exists. So the JVM cannot terminate because - simple as that - a thread still exists.
There are two ways to terminate the JVM instance from the running application: Calling the exit() method, which initiates the JVM normal shutdown sequence: run all registered shutdown hooks; run all uninvoked finalizers; then end the JVM instance. Calling the halt() method, which ends the JVM instance immediately.
Scorpion lead me to the right answer:
RMI Reaper
is something like a garbage collector for remote objects, e.g. instances of (subclasses of) UnicastRemoteObject
. It is a non-daemon thread and therefore blocks JVM termination if there are still exported objects which can not be cleaned up.
You can explicity force remote objects to be cleaned up in this sense by passing them to UnicastRemoteObject.unexportObject(., true)
. If you do this on all previously exported objects, RMI Reaper
terminates and JVM is free to shut down.
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