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