A scheduler starts a java application, which ends without any problem most of the time.
Sometimes however, the java.exe process doesn't end. As far we can see, the java application itself has ended, but the java.exe process not. There is not solution but to kill it.
The Process Explorer shows only one thread (in sense of the OS, not of java) for this process. It hat the state "Wait:WrKeyedEvent" and following stack
ntoskrnl.exe!KeWaitForMultipleObjects+0x0a
ntoskrnl.exe!ExfReleasePushLock+0x8ec
ntoskrnl.exe!_misaligned_access+0x331
ntdll.dll!ZwReleaseKeyedEvent+0xa
ntdll.dll!RtlFindMostSignificatBit+0xa0
ntdll.dll!RtlProcessFlsData+0xdc
ntdll.dll!LdrShutdownProcess+0xa9
ntdll.dll!RtlExitUserProcess+0x90
msvcrt.dll!wcstoui64+0x2fa
jvm.dll!JVM_Clone
jvm.dll!JVM_Clone
jvm.dll!JVM_Clone
jvm.dll!JVM_Clone
jvm.dll!JVM_Clone
jvm.dll!JVM_FindSignal
msvcrt.dll!srand
msvcrt.dll!ftime64_s
kernel32.dll!BaseThreadInitThunk
ntdll.dll!RtlUserThreadStart
Has somebody an idea, why java.exe does not end?
Edit about the response "one no-deamon thread is still running"
The problem is not a remaining thread in the Java application. An Java application has several running (Java-)threads, even if only one of it is a no-deamon one.
This is also true for a ShutdownHook. See this example:
/** Main class */
public class TestShutdown
{
public static void main (final String[] args) throws FileNotFoundException
{
Runtime.getRuntime().addShutdownHook(new HookThread());
}
}
/** The hook Thread */
final class HookThread extends Thread
{
public HookThread()
{
super(HookThread.class.getName();
}
@Override
public void run()
{
try
{
sleep(5000l);
} catch (final InterruptedException ex) { throw new Error(); }
final StringBuilder sb = new StringBuilder();
Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
sb.append("Number of threads: " + traces.size() + "\n");
for (final Thread th: traces.keySet())
{
sb.append("-----------------\n");
sb.append(th.toString()+" "+ (th.isDaemon() ? " (deamon) " : " (not deamon) ") + "\n");
final StackTraceElement[] trace = traces.get(th);
for (int j=0; j < trace.length; j++)
sb.append(" at " + trace[j] + "\n");
}
System.out.println(sb.toString());
}
}
and the result:
Number of threads: 6
-----------------
Thread[Reference Handler,10,system] (deamon)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
-----------------
Thread[Finalizer,8,system] (deamon)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
-----------------
Thread[HookThread,5,main] (not deamon)
at java.lang.Thread.dumpThreads(Native Method)
at java.lang.Thread.getAllStackTraces(Unknown Source)
at HookThread.run(TestShutdown.java:59)
-----------------
Thread[Attach Listener,5,system] (deamon)
-----------------
Thread[DestroyJavaVM,5,main] (not deamon)
at java.lang.Object.wait(Native Method)
at java.lang.Thread.join(Unknown Source)
at java.lang.Thread.join(Unknown Source)
at java.lang.ApplicationShutdownHooks.runHooks(Unknown Source)
at java.lang.ApplicationShutdownHooks$1.run(Unknown Source)
at java.lang.Shutdown.runHooks(Unknown Source)
at java.lang.Shutdown.sequence(Unknown Source)
at java.lang.Shutdown.shutdown(Unknown Source)
-----------------
Thread[Signal Dispatcher,9,system] (deamon)
(By the way: in this case we have two not deamons: the hook thread and the DestroyJavaVM
, which has started the hook and waits until it ends.)
But moreover: my hanging java.exe has only one OS-thread! And it's clear that the program java.exe must hava more threads as the application which is running in its virtual machine... (whith the above programm, 6 Java-threads are running in the VM but the java.exe process itself hat 17 OS-threads.)