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

ConstantPool::release_C_heap_structures not run in some circumstances

    Details

    • Subcomponent:
    • Resolved In Build:
      b122

      Backports

        Description

        JDK 8 is leaking memory in VM_RedefineClasses::merge_cp_and_rewrite when repeating class redefinition:

        [0x00002aaaab1c2d5a] ConstantPool::ConstantPool(Array<unsigned char>*)+0x6a
        [0x00002aaaab1c307c] ConstantPool::allocate(ClassLoaderData*, int, Thread*)+0x14c
        [0x00002aaaab48aa7e] VM_RedefineClasses::merge_cp_and_rewrite(instanceKlassHandle, instanceKlassHandle, Thread*)+0x5e
        [0x00002aaaab48b5d3] VM_RedefineClasses::load_new_class_versions(Thread*)+0x4c3
                    (malloc=84362KB #719885)

          Issue Links

            Activity

            Hide
            dcubed Daniel Daugherty added a comment - - edited
            Moved to core-svc/java.lang.instrument since the test case appears to use JLI/JPLIS...

            Update: If the leak is due to something in the JVM/TI layer, then this
            bug should be moved to hotspot/jvmti.
            Show
            dcubed Daniel Daugherty added a comment - - edited Moved to core-svc/java.lang.instrument since the test case appears to use JLI/JPLIS... Update: If the leak is due to something in the JVM/TI layer, then this bug should be moved to hotspot/jvmti.
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment - - edited
            This is because the merge constant pool used by class redefinition is not removed properly, even though it's added to the classloader _deallocate_list.

            I think this is because ClassLoaderDataGraph::do_unloading removes the related classloader from the graph because it is not live, and then runs the ClassLoaderData destructor without cleaning out the _deallocate_list first.

            This is fixed in 9, most likely by JDK-8061205. Working on verifying that.

            Two ways of fixing this, either make sure the _deallocate_list is cleaned in ClassLoaderData::~ClassLoaderData, or backport JDK-8061205.

            Changing this to hotspot/runtime since that's what JDK-8061205 is set to.
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - - edited This is because the merge constant pool used by class redefinition is not removed properly, even though it's added to the classloader _deallocate_list. I think this is because ClassLoaderDataGraph::do_unloading removes the related classloader from the graph because it is not live, and then runs the ClassLoaderData destructor without cleaning out the _deallocate_list first. This is fixed in 9, most likely by JDK-8061205 . Working on verifying that. Two ways of fixing this, either make sure the _deallocate_list is cleaned in ClassLoaderData::~ClassLoaderData, or backport JDK-8061205 . Changing this to hotspot/runtime since that's what JDK-8061205 is set to.
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment -
            Doesn't look like its JDK-8061205 that fixed this in JDK 9, still working on finding out which change it was.
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - Doesn't look like its JDK-8061205 that fixed this in JDK 9, still working on finding out which change it was.
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment -
            Looks like it was JDK-8026977 that fixed it in JDK 9.
            It might be a bit problematic to backport, so I'll probably do a JDK 8 specific fix for the leak.
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - Looks like it was JDK-8026977 that fixed it in JDK 9. It might be a bit problematic to backport, so I'll probably do a JDK 8 specific fix for the leak.
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment -
            The leak fixed in JDK-8026977 might also be unrelated - I can't really tell without further investigation, since the NMT detail tracking was not finished in that build.
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - The leak fixed in JDK-8026977 might also be unrelated - I can't really tell without further investigation, since the NMT detail tracking was not finished in that build.
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment -
            After discussing this with Stefan Karlsson, I'm convinced that it is the above change that fixed the memory leak.
            Usually, a direct free of a constant pool is not needed if the holding ClassLoaderData is going away, since memory is reclaimed automatically because it's part of the metaspace.
            However, a lock allocated in the constant pool (introduced by JDK-8014910, removed in JDK 9 by JDK-8026977) is not part of the metaspace, and can therefore be leaked under the circumstances mentioned above (classloader marked as not live).
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - After discussing this with Stefan Karlsson, I'm convinced that it is the above change that fixed the memory leak. Usually, a direct free of a constant pool is not needed if the holding ClassLoaderData is going away, since memory is reclaimed automatically because it's part of the metaspace. However, a lock allocated in the constant pool (introduced by JDK-8014910, removed in JDK 9 by JDK-8026977 ) is not part of the metaspace, and can therefore be leaked under the circumstances mentioned above (classloader marked as not live).
            Hide
            aeriksso Andreas Eriksson (Inactive) added a comment - - edited
            For JDK 9 ConstantPool::release_C_heap_structures is not run either. It has no lock to leak, but a call to ConstantPool::unreference_symbols done there will never be called.
            Show
            aeriksso Andreas Eriksson (Inactive) added a comment - - edited For JDK 9 ConstantPool::release_C_heap_structures is not run either. It has no lock to leak, but a call to ConstantPool::unreference_symbols done there will never be called.
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/hs/hotspot/rev/6586b45fe833
            User: aeriksso
            Date: 2016-05-19 11:23:41 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/hs/hotspot/rev/6586b45fe833 User: aeriksso Date: 2016-05-19 11:23:41 +0000
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/6586b45fe833
            User: lana
            Date: 2016-06-08 20:34:57 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/6586b45fe833 User: lana Date: 2016-06-08 20:34:57 +0000

              People

              • Assignee:
                aeriksso Andreas Eriksson (Inactive)
                Reporter:
                shadowbug Shadow Bug
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: