Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8187882

Replace ClassLoader use of finalizer with phantom reference to unload native library

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Withdrawn
    • Icon: P3 P3
    • None
    • core-libs
    • None
    • behavioral
    • medium
    • Hide
      There are two behavioral changes. First, this change may affect the timing on when a native library is being unloaded because it is now handled by the system cleaner thread rather than the finalizer thread that is subject to the thread scheduling. Note that it is unspecified when a native library is unloaded. This behavior is solely implementation-dependent. The native library will be unloaded when a class loader becomes phantom reachable and the cleaner thread is in action to invoke the cleaning method. Previously, the native library will be unloaded when a class loader becomes finalizable and the finalizer thread is in action to invoke the finalizer. It is expected that this behavioral change should not be noticeable except the native library is being reloaded immediately when the class loader is GC'ed before the system cleaner thread gets a chance to handle the unloading of that class loader.

      Second, JNI_OnUnload calling JNI_FindClass can only find classes visible to the system class loader or its ancestor. Existing native library expects to find classes defined to this unloaded class loader or its ancestors that is not a built-in class loader will no longer work. It is specified in the spec for JNI_OnUnload that the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.

      It is believed that the compatibility risk should be low but marked as medium because it is uncertain how existing applications depend on these behaviors.
      Show
      There are two behavioral changes. First, this change may affect the timing on when a native library is being unloaded because it is now handled by the system cleaner thread rather than the finalizer thread that is subject to the thread scheduling. Note that it is unspecified when a native library is unloaded. This behavior is solely implementation-dependent. The native library will be unloaded when a class loader becomes phantom reachable and the cleaner thread is in action to invoke the cleaning method. Previously, the native library will be unloaded when a class loader becomes finalizable and the finalizer thread is in action to invoke the finalizer. It is expected that this behavioral change should not be noticeable except the native library is being reloaded immediately when the class loader is GC'ed before the system cleaner thread gets a chance to handle the unloading of that class loader. Second, JNI_OnUnload calling JNI_FindClass can only find classes visible to the system class loader or its ancestor. Existing native library expects to find classes defined to this unloaded class loader or its ancestors that is not a built-in class loader will no longer work. It is specified in the spec for JNI_OnUnload that the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs. It is believed that the compatibility risk should be low but marked as medium because it is uncertain how existing applications depend on these behaviors.

      Summary

      Convert the ClassLoader implementation from its use of finalizer to phantom reference to handle unloading of a native library when a class loader is unloaded.

      Problem

      The finalization mechanism is inherently problematic and the JDK implementation should migrate away from its use of finalizers.

      Solution

      Use java.lang.ref.Cleaner to register the class loader and the action to unload a native library.

      Specification

      • JNI_FindClass

        Specify that JNI_FindClass uses the system class loader as its context for finding class when JNI_FindClass is called from JNI_OnUnload or JNI_OnUnload_L.

        This is behavioral change because the hotspot implementation has been using the class loader associated with the native library as the current context. It is a bug because the spec of JNI_OnUnload specifies that it is called in an unknown context (such as from a finalizer).

      • JNI_OnUnload and JNI_OnUnload_L

        Change the spec as follows to reflect that the native library may be unloaded after the class loader is GC'ed.

        -Optional function defined by dynamically linked libraries. The VM calls
        -`JNI_OnUnload` when the class loader containing the native library is garbage
        -collected.
        +Optional function defined by dynamically linked libraries.
        +When the class loader containing the native library is garbage collected,
        +the VM registers `JNI_OnUnload` to be invoked when the native library
        +is being unloaded.  It is not specified when the `JNI_OnUnload` function
        +is invoked and the native library is unloaded.
        

        -Optional function defined by statically linked libraries. When the class loader
        -containing a statically linked native library 'L' is garbage collected, the VM
        -will invoke the JNI_OnUnload_L function of the library if such a function is
        -exported.
        +Optional function defined by statically linked libraries.
        +When the class loader containing a statically linked native library 'L'
        +is garbage collected, the VM registers JNI_OnUnload_L to be invoked
        +if such a function is exported.  It is not specified when the 
        +JNI_OnUnload_L function is invoked.

            mchung Mandy Chung (Inactive)
            mchung Mandy Chung (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: