Author: markt Date: Tue Mar 8 19:41:07 2016 New Revision: 1734128 URL: http://svn.apache.org/viewvc?rev=1734128&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=59138 Correct a false positive warning for ThreadLocal related memory leaks when the key class but not the value class has been loaded by the web application class loader.
Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/loader/LocalStrings_es.properties tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=1734128&r1=1734127&r2=1734128&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties Tue Mar 8 19:41:07 2016 @@ -28,7 +28,8 @@ webappClassLoader.checkThreadLocalsForLe webappClassLoader.checkThreadLocalsForLeaks.badValue=Unable to determine string representation of value of type [{0}] webappClassLoader.checkThreadLocalsForLeaks.unknown=Unknown webappClassLoader.checkThreadLocalsForLeaks=The web application [{0}] created a ThreadLocal with key of type [{1}] (value [{2}]) and a value of type [{3}] (value [{4}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. -webappClassLoader.checkThreadLocalsForLeaksDebug=The web application [{0}] created a ThreadLocal with key of type [{1}] (value [{2}]). The ThreadLocal has been correctly set to null and the key will be removed by GC. +webappClassLoader.checkThreadLocalsForLeaksNone=The web application [{0}] created a ThreadLocal with key of type [{1}] (value [{2}]) and a value of type [{3}] (value [{4}]). Since keys are only weakly held by the ThreadLocal Map this is not a memory leak. +webappClassLoader.checkThreadLocalsForLeaksNull=The web application [{0}] created a ThreadLocal with key of type [{1}] (value [{2}]). The ThreadLocal has been correctly set to null and the key will be removed by GC. webappClassLoader.checkThreadLocalsForLeaksFail=Failed to check for ThreadLocal references for web application [{0}] webappClassLoader.checkThreadsHttpClient=Found HttpClient keep-alive thread using web application class loader. Fixed by switching thread to the parent class loader. webappClassLoader.getThreadGroupError=Unable to obtain the parent for ThreadGroup [{0}]. It will not be possible to check all threads for potential memory leaks Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings_es.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings_es.properties?rev=1734128&r1=1734127&r2=1734128&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings_es.properties (original) +++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings_es.properties Tue Mar 8 19:41:07 2016 @@ -25,7 +25,7 @@ webappClassLoader.checkThreadLocalsForLe webappClassLoader.checkThreadLocalsForLeaks.badValue = No puedo determinar la representaci\u00F3n de cadena del valor del tipo [{0}] webappClassLoader.checkThreadLocalsForLeaks.unknown = Desconocido webappClassLoader.checkThreadLocalsForLeaks = La aplicaci\u00F3n web [{0}] cre\u00F3 un ThreadLocal con clave del tipo [{1}] (valor [{2}]) y un valor del tipo [{3}] (valor [{4}]) pero no pudo quitarlo cuando la aplicaci\u00F3n web se par\u00F3. Los hilos se van a renovar con el tiempo para intentar evitar in posible fallo de memoria. -webappClassLoader.checkThreadLocalsForLeaksDebug = La aplicaci\u00F3n web [{0}] cre\u00F3 un ThreadLocal con clave del tipo [{1}] (valor [{2}]). El Threadlocal ha sido puesto correctamente a nulo y la clave ser\u00E1 qutada por el GC. +webappClassLoader.checkThreadLocalsForLeaksNull = La aplicaci\u00F3n web [{0}] cre\u00F3 un ThreadLocal con clave del tipo [{1}] (valor [{2}]). El Threadlocal ha sido puesto correctamente a nulo y la clave ser\u00E1 qutada por el GC. webappClassLoader.checkThreadLocalsForLeaksFail = No pude revisar las referencias a ThreadLocal para la aplicaci\u00F3n web [{0}] webappClassLoader.checkThreadsHttpClient = Hallado hilo keep-alive de HttpClient usando cargador de clase de aplicaci\u00F3n web. Fijado por el hilo de conmutaci\u00F3n al cargador de la clase padre. webappClassLoader.stopThreadFail = No pude terminar el hilo con nombre [{0}] para la aplicaci\u00F3n web [{1}] Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java?rev=1734128&r1=1734127&r2=1734128&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java Tue Mar 8 19:41:07 2016 @@ -2043,11 +2043,12 @@ public abstract class WebappClassLoaderB for (int j =0; j < table.length; j++) { Object obj = table[j]; if (obj != null) { - boolean potentialLeak = false; + boolean keyLoadedByWebapp = false; + boolean valueLoadedByWebapp = false; // Check the key Object key = ((Reference<?>) obj).get(); if (this.equals(key) || loadedByThisOrChild(key)) { - potentialLeak = true; + keyLoadedByWebapp = true; } // Check the value Field valueField = @@ -2055,9 +2056,9 @@ public abstract class WebappClassLoaderB valueField.setAccessible(true); Object value = valueField.get(obj); if (this.equals(value) || loadedByThisOrChild(value)) { - potentialLeak = true; + valueLoadedByWebapp = true; } - if (potentialLeak) { + if (keyLoadedByWebapp || valueLoadedByWebapp) { Object[] args = new Object[5]; args[0] = getContextName(); if (key != null) { @@ -2084,16 +2085,22 @@ public abstract class WebappClassLoaderB "webappClassLoader.checkThreadLocalsForLeaks.unknown"); } } - if (value == null) { + if (valueLoadedByWebapp) { + log.error(sm.getString( + "webappClassLoader.checkThreadLocalsForLeaks", + args)); + } else if (value == null) { if (log.isDebugEnabled()) { log.debug(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaksDebug", + "webappClassLoader.checkThreadLocalsForLeaksNull", args)); } } else { - log.error(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks", - args)); + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "webappClassLoader.checkThreadLocalsForLeaksNone", + args)); + } } } } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1734128&r1=1734127&r2=1734128&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 8 19:41:07 2016 @@ -165,6 +165,11 @@ Implement the proposed Servlet 4.0 API to provide mapping type information for the current request. (markt) </add> + <fix> + <bug>59138</bug>: Correct a false positive warning for ThreadLocal + related memory leaks when the key class but not the value class has been + loaded by the web application class loader. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org