Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-9742

ClassLoader leak in JBoss Threads caused by MDBs

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 11.0.0.Final
    • Fix Version/s: 12.0.0.Final
    • Component/s: None
    • Labels:
      None
    • Steps to Reproduce:
      Hide

      While this can be reproduced with any MDB, I attached a small example project which can be used for this. Steps to reproduce:

      1. Deploy module containing any MDB
      2. Undeploy module
      3. Create heap dump of the WildFly process
      4. Open heap dump in Eclipse Memory Analyzer
      5. Browse to thread view, look for thread named "default-threads - 1"
      6. The thread's contextClassLoader will still point to the ModuleClassLoader of the undeployed module (see attached screenshot)
      Show
      While this can be reproduced with any MDB, I attached a small example project which can be used for this. Steps to reproduce: Deploy module containing any MDB Undeploy module Create heap dump of the WildFly process Open heap dump in Eclipse Memory Analyzer Browse to thread view, look for thread named "default-threads - 1" The thread's contextClassLoader will still point to the ModuleClassLoader of the undeployed module (see attached screenshot)

      Description

      There is a classloader leak in JBoss Threads which is most noticable when deploying MDBs. When a new MDB is created and a new thread for the MDB is started in the JCA thread pool ("default-threads - x"), the thread will be created using the context classloader of the MDB's deployment unit. This is because MessageDrivenComponent.activate() sets the context classloader of the ServerService thread in order to create the MDB, and this classloader will then also be used by the child thread.

      In the default configuration, the threads in the default thread pool will not be terminated and therefore the thread will keep the reference to the classloader even when the deployment unit is undeployed. This in turn can lead to "OutOfMemoryError: Metaspace" after a couple of redeployments.

      As a workaround, we changed JBossThreadFactory.createThread() to set the context classloader to null after a new thread has been created. While this fixes the issue for us, I am not sure whether this is a good solution for all consumers of the thread factory, or if this should be fixed in the JCA subsystem instead. That's also the reason why I opened this issue against the WildFly project instead of JBoss Threads.

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  dmlloyd David Lloyd
                  Reporter:
                  markusdlugi Markus Dlugi
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: