JNI DetachCurrentThread() usage during JVM process exit
Darryl L. Miles
darryl-mailinglists at netbauds.net
Tue Oct 16 05:57:47 PDT 2012
I am trying to understand the reasons why the JNI method
DetachCurrentThread() blocks the thread in VM_Exit::wait_if_vm_exited()
instead of returning control back to JNI during process exit proceedings.
This is particular problematic when the thread in question is actually
owned by JNI (because it started out life with JNI using
pthread_create() directly).
Sequence of events:
* java.exe starts up
* JAR loaded and JNI *.so loaded
* addShutdownHook() thread added
* application uses/implements JNI based thread pool, this creates a
thread, that does work, completes and stays idle in pool. During the
time of doing work it performs a JNI AttachCurrentThreadAsDaemon() so it
can call into Java. Not all JNI threads created call into Java, they
are attached to VM on their first invocation into Java and remain
attached. If the thread pool prunes (terminates) idle workers, those
threads will call DetachCurrentThread() if they had been attached before
the worker thread exits.
* The Application decides to exit, the JNI based thread pool has no
active threads but may have management thread and one or more workers
that are idle in the pool.
* System.exit() is called.
* addShutdownHook() thread started and run
* From the shutdownHook thread this instructs the JNI based thread pool
to close, during this close each worker thread that did an
'AttachCurrentThreadAsDaemon()' will perform a 'DetachCurrentThread()'.
These threads hang because the JVM never returns control back to JNI.
These threads are owned by JNI (not by Java) so they may have further
clean up to do and will then exit if the DetachCurrentThread() were to
return control.
* The addShutdownHook() thread deadlocks waiting for the JNI thread pool
to close.
I can understand if the thread started out life as Java Thread object or
as an internal house keeping thread (that scenario is unlikely to call
any of my JNI).
But when the thread started out life from JNI using pthread_create() and
then was introduced to the JVM, I think that JNI DetachCurrentThread()
should not block even on exit under these circumstances. If anything
the DetachCurrentThread() is signalling that Java has no further need to
worry about this thread anymore, i.e. it can not invoke any Java.
Obviously I would expect the JVM to refuse any further Attach requests
under a VM_Exit scenario.
I think JVM thread accounting should handle this case, maybe defer TLS
cleanup if it is not possible to touch some data due to locking, or just
never cleanup if the process is going to terminate anyway.
TIA,
Darryl
More information about the hotspot-dev
mailing list