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

Reply via email to