Uploaded image for project: 'JBoss Marshalling'
  1. JBoss Marshalling
  2. JBMAR-225

Metaspace Memory Leak - SerializableClassRegistry Prevents ClassLoader Garbage Collection

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 2.0.7.Final
    • Marshalling API
    • None
    • Hide
      • Download the attached TestCase.zip and extract it to a location of your choosing.
      • There is a run.sh script in the archive that compiles the test code and executes it.
      • Here is what the test script + code does:
        • Loads jboss-marshalling 2.0.7.Final using a URLClassLoader and causes some SerializableClass instances to get cached
        • Closes the URLClassLoader
        • Repeats the previous two steps until the JVM runs out of metaspace (227 iterations when I ran it)
        • The script then waits for the user to hit enter and then re-runs the same program, but uses a patched jboss-marshalling jar (patch file included in the zip archive)
        • The program is able to load and unload jboss-marshalling with the URLClassLoader 5000 times before it gracefully stops

      The patched jboss-marshalling and attached patch file are meant to just be a proof of concept of the solution idea

      Show
      Download the attached TestCase.zip and extract it to a location of your choosing. There is a run.sh script in the archive that compiles the test code and executes it. Here is what the test script + code does: Loads jboss-marshalling 2.0.7.Final using a URLClassLoader and causes some SerializableClass instances to get cached Closes the URLClassLoader Repeats the previous two steps until the JVM runs out of metaspace (227 iterations when I ran it) The script then waits for the user to hit enter and then re-runs the same program, but uses a patched jboss-marshalling jar (patch file included in the zip archive) The program is able to load and unload jboss-marshalling with the URLClassLoader 5000 times before it gracefully stops The patched jboss-marshalling and attached patch file are meant to just be a proof of concept of the solution idea

    Description

      jboss marshalling caches SerailizableClass instances using Java's ClassValue API. The intention here is to be able to weakly cache stuff using the java.lang.Class instance as the cache key while also referencing the java.lang.Class in the cache value (SerializableClass).

      Unfortunately, the solution as it stands prevents ClassLoader garbage collection because SeriallzableClassRegistry keeps the ClassValue instance as a static variable which creates a hard reference chain between the ClassLoader and the ClassValue instance:

      Some ClassLoader -> SerializableClassRegistry.class -> ClassValue instance
      

      In this case, "Some ClassLoader" is a plugin/module class loader with an augmented class path compared to the System class loader.

      The reason "Some ClassLoader" can't be GCed is because there is reference chain starting at the System Class loader that is preventing it that looks something like this:

      System ClassLoader -> java.util.HashMap.class (this could be any Serializable class loaded by the System ClassLoader) ->
      classValueMap -> SerilizableClass.class (entry in the map) -> "Some ClassLoader" (it loaded SerializableClass)
      

      Attachments

        Activity

          People

            dlloyd@redhat.com David Lloyd
            jswett33 Joshua Swett (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: