JDK-6332506 : DestroyJavaVM not terminating the VM leading to failure of subsequent boots; need restartable JVM
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 5.0u8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2005-10-04
  • Updated: 2011-02-16
  • Resolved: 2005-10-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0-poolResolved
Description
My integration efforts work towards dynamically loading the JVM shared
  object and creating the VM per JNI_CreateJavaVM whenever there is need
  for such.  Ie the execution of methods invoked per native calls.

  Once our database work (JNI/VM dependencies) completed and no new
  work is in the pipe-line we like to shutdown the VM as it may hold
  platform resources.  An other situation to terminate the VM is to
  unload it for administrative purposes.

  Unfortunately the J2SE seems incapable destroying the VM.  Ie below
  minimum listed sequence demonstrates such already.

    JavaVM    *jvm;
    JNIEnv    *env;
    JavaVMInitArgs    vm_args;

        .. setup required vm_args ..

    JNI_CreateJavaVM (&jvm, &env, &vm_args)

        .. issue JNI requests towards the VM ..

    (jvm)->DestroyJavaVM()

  The call DestroyJavaVM() returns 0 indicating success, but platform
  debuggers learn me that afterwards certain service threads are still
  operational holding resources provoking us from launching it again.
  Needless to say that we can't terminate the entire database server
  to establish such.

  Going over the Sun documentation and reading various news groups this
  seems a problem around found by many users/developers.

  Documentation learns me:
    "Eventually the program calls the DestroyJavaVM function to
     unload the Java virtual machine. (Unfortunately, you cannot
     unload the Java virtual machine implementation in JDK release
     1.1 or Java 2 SDK release 1.2. DestroyJavaVM always returns an
     error code in these releases.)"

  We are developing our integration work with:
    vm_info: Java HotSpot(TM) Client VM (1.5.0_04-b05) for linux-x86, built on Jun  3 2005 03:17:33 by java_re with gcc 3.2.1-7a (J2SE release)

  I assume this is an JVM internal bug which seems around on many
  releases and platforms.  If so i think it should be escalated.

  Could you sched some light on this issue?  Are there additional ways
  to destroy (gracefully shutdown) the JVM allowing me to temporarily
  workaround this issue? 
----------------------



###@###.### 10/04/05

> Your suggested dlclose() on the handle unfortunate doesn't help, as within the
> J2SE client lib code many other shared objects are dynamically loaded
> (nesting) where as certain threads still keep active these libs stay
> referenced within the main program.  So effectively i am stuck with
> a load once scenario for the moment.


No question it can be hard to dlclose any library in a multi-threaded
environment. Also if I wasn't clear in my previous email, I didn't
mean you can dlclose libjvm.so now. It would only become possible
if we can change daemon threads to self-terminate so we don't have
to keep VM logic around. If you try to dlclose libjvm.so now, it will
cause intermittent crashes.

Restartable VM has been a wish-list item for a long time. I'll file
a RFE for library team to terminate daemon threads and a VM bug to
follow up.

thanks,
-hui

>>
>> You are right the issue has been around since day 1. But no, it's
>> NOT fixed. There are fundamental difficulties in implementing a
>> clean shutdown.
>>
>> As a user land application, VM can't terminate any thread by
>> force. Otherwise we will just end up in deadlocks. Aware of the
>> problem, DestroyJavaVM() is designed such that it will block
>> current thread until all Java threads are gone before VM can
>> start the shutdown sequence. However, Java also has daemon thread
>> which is designed to bypass this restriction and explicitly
>> allow VM shutdown when there may be threads running Java/native
>> code. So that leaves us with no choice but to keep VM logic in
>> place to provide some basic functionality for the daemon threads.
>>
>> That said, most Java applications don't create any daemon threads
>> at all. The only daemon threads in most applications are the ones
>> that are created by JDK (reference handler, finalizer thread, etc).
>> We should modify them so that they can receive VM notifications on
>> shutdown and terminate themselves cleanly (e.g. by using a Java
>> shutdown hook to send notifications). If this can be implemented,
>> at least we should be able to terminate JVM for most Java applications.
>>
>> Restarting JVM in the same process is harder, because there are
>> assumptions in the VM that it's started from clean. But presumably
>> after a clean shutdown you could just dlclose() and then dlopen()
>> to give VM a fresh start.
>>
>> As to returning 0 from DestroyJavaVM(), it can be seen as a minor
>> HotSpot bug, because clearly we are not terminating the whole VM.
>> When we can cleanly terminate the VM (at least for some applications),
>> we should change to return 0 for those apps and -1 for applications
>> that can't be terminated cleanly.
>>
>> thanks,
>> -hui