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

AddressChangeListener thread inherits CCL and can cause memory leak for webapp-servers

    XMLWordPrintable

Details

    • b24
    • generic
    • windows

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Java 17
      Windows 2019 and Win 10 (but should be independent of OS)

      A DESCRIPTION OF THE PROBLEM :
      We are using Tomcat 10 with Java 17 and when redeploying our web-application, a memory leak is reported.

      Cause:
      The class sun.net.dns.ResolverConfigurationImpl spawns a threads of the internal class AddressChangeListener.
      This thread is connected to the classloader of the web-application.
      During undeployment the classloader is removed by tomcat and should be garbage collected. The spawned thread however still has a reference to the web-app classloader and thus won't get garbage-collected

      Tomcat issues a warning on undeployment:
      WARNING: The web application [test] appears to have started a thread named [Thread-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
       sun.net.dns.ResolverConfigurationImpl.notifyAddrChange0(Native Method)
       sun.net.dns.ResolverConfigurationImpl$AddressChangeListener.run(ResolverConfigurationImpl.java:144)
      ...
      A very similar bug was fixed recently: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8273831
      The solution should also work for this problem. The setContextClassLoader was called to remove the reference to the web-app-classloader.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Insert the followint lines into a web-application, call the jsp and then undeploy the app / war-file:
          Hashtable<String, String> env = new Hashtable();
          env.put( "java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory" );
          DirContext dns = new InitialDirContext( env );

      These 3 lines will trigger the creation of the AddressChangeListener-Thread.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The thread should run without a reference to the web-app classloader.
      ACTUAL -
      The spawned thread holds a reference to the web-app-classloader (as the context-classloader)

      CUSTOMER SUBMITTED WORKAROUND :
      A possible workaround is to change the context-classloader before doing DNS-stuff:
      Classloader cl = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(cl.getParent());
      // do dns stuff and then set old classloader

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              jpai Jaikiran Pai
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: