-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 18, 19
-
b24
-
generic
-
windows
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
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