You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/03/09 20:13:18 UTC

svn commit: r1298986 - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/catalina/loader/ test/org/apache/catalina/loader/ webapps/docs/

Author: markt
Date: Fri Mar  9 19:13:18 2012
New Revision: 1298986

URL: http://svn.apache.org/viewvc?rev=1298986&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52850
Enable the memoey leak protection code to play nicely with IBM JVMs as
well as Oracle JVMs.
Extend test case coverage of memory leak protection.
Patch provided by Rohit Kelapure.

Added:
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java   (props changed)
      - copied unchanged from r1298983, tomcat/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderThreadLocalMemoryLeak.java   (props changed)
      - copied unchanged from r1298983, tomcat/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderThreadLocalMemoryLeak.java
Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Mar  9 19:13:18 2012
@@ -1 +1 @@
-/tomcat/trunk:1156115-1157160,1157162-1157859,1157862-1157942,1157945-1160347,1160349-1163716,1163718-1166689,1166691-1174340,1174342-1175596,1175598-1175611,1175613-1175932,1175934-1177783,1177850,1177862,1177978,1178209,1178228,1178233,1178449,1178542,1178681,1178684,1178721,1179268,1179274,1180261,1180865,1180891,1180894,1180907,1181028,1181123,1181125,1181136,1181291,1181743,1182796,1183078,1183105,1183142,1183328,1183339-1183340,1183492-1183494,1183605,1184917,1184919,1185018,1185020,1185200,1185588,1185626,1185756,1185758,1186011,1186042-1186045,1186104,1186123,1186137,1186153,1186254,1186257,1186377-1186379,1186479-1186480,1186712,1186743,1186750,1186763,1186890-1186892,1186894,1186949,1187018,1187027-1187028,1187381,1187753,1187755,1187775,1187801,1187806,1187809,1187827,1188301,1188303-1188305,1188399,1188822,1188930-1188931,1189116,1189129,1189183,1189240,1189256,1189386,1189413-1189414,1189477,1189685,1189805,1189857,1189864,1189882,1190034,1190185,1190279,1190339
 ,1190371,1190388-1190389,1190474,1190481,1194915,1195222-1195223,1195531,1195899,1195905,1195943,1195949,1195953,1195955,1195965,1195968,1196175,1196212,1196223,1196304-1196305,1196735,1196825,1196827,1197158,1197261,1197263,1197299-1197300,1197305,1197339-1197340,1197343,1197382,1197386-1197387,1197480,1197578,1198497,1198528,1198552,1198602,1198604,1198607,1198622,1198640,1198696,1198707,1199418,1199432,1199436,1199513,1199529,1199980,1199996,1200056,1200089,1200106-1200107,1200263,1200316,1200320,1200398-1200399,1200445-1200446,1200555,1200627,1200696,1200725,1200937,1200941,1201069,1201087,1201180,1201235-1201237,1201508,1201521,1201542,1201545-1201546,1201548,1201555-1201556,1201568,1201576,1201608,1201921-1201922,1201931,1202035,1202039,1202271,1202565,1202578,1202705,1202828,1202860,1203047-1203052,1203078,1203091,1203253,1203278,1204182,1204856,1204867,1204936,1204938,1204982,1205033,1205065,1205082,1205097,1205112,1206200,1207692,1208046,1208073,1208096,1208114,1208
 145,1208772,1209194,1209277-1209278,1209686-1209731,1210894,1212091,1212095,1212099,1212118,1213469,1213906,1214853,1214855,1214864,1215115,1215118-1215119,1215121,1220293,1220295,1221038,1221842,1222189,1222201,1222276,1222300,1222690,1222850,1222852,1222855,1224607,1224617,1224648-1224652,1224657,1224662-1224663,1224682,1224801,1224910,1225000,1225219,1225343,1225465,1225627,1225629,1225634,1226069,1226158-1226159,1226177,1226196,1226214-1226215,1226385,1226394,1226500,1226537-1226538,1226546,1226551,1226975,1228196,1228360,1228376,1228724,1228908,1228918,1228920,1228922,1228929,1228969,1229307,1229536,1229549,1229724,1229726-1229731,1229997,1230539,1230711,1230729,1230762-1230763,1230765,1230955,1230957,1231285,1231290,1231308,1231310,1231337,1231460-1231461,1231542-1231543,1231546-1231547,1231620-1231621,1231624-1231625,1231630,1231654-1231655,1231738,1231740,1231762-1231763,1231856,1231886,1231923,1231947,1232345,1232368,1232380,1232447,1232760,1232813,1232842-1232843,1
 232869,1233413,1233423,1233426,1234143,1234567,1235207,1236906-1236907,1236914,1237146,1237154-1237156,1237332,1237334,1237425,1237427,1237604,1237975,1237981,1237985,1238070,1238073,1239024,1239048,1239050,1239060,1239135,1239483,1239485,1240101,1240106,1240109,1240112,1240114,1240116,1240118,1240121,1240329,1240697,1240795,1240821,1240842,1240857,1241087,1241160,1241908-1241909,1241982,1242099,1242110,1242371,1242434,1242495,1242947,1243034,1243038,1244302,1244511,1244567,1244718-1244719,1244935-1244938,1245274,1245449,1245849,1290875,1292334,1292338,1292345-1292347,1293155,1293831-1293832,1295998,1297014-1297015,1297017,1297158,1297177,1297202,1297209,1297213,1297717,1297722,1297729,1297768,1297778,1297818,1297828,1297979,1297987,1298121,1298140,1298590,1298592,1298628-1298629,1298794
+/tomcat/trunk:1156115-1157160,1157162-1157859,1157862-1157942,1157945-1160347,1160349-1163716,1163718-1166689,1166691-1174340,1174342-1175596,1175598-1175611,1175613-1175932,1175934-1177783,1177850,1177862,1177978,1178209,1178228,1178233,1178449,1178542,1178681,1178684,1178721,1179268,1179274,1180261,1180865,1180891,1180894,1180907,1181028,1181123,1181125,1181136,1181291,1181743,1182796,1183078,1183105,1183142,1183328,1183339-1183340,1183492-1183494,1183605,1184917,1184919,1185018,1185020,1185200,1185588,1185626,1185756,1185758,1186011,1186042-1186045,1186104,1186123,1186137,1186153,1186254,1186257,1186377-1186379,1186479-1186480,1186712,1186743,1186750,1186763,1186890-1186892,1186894,1186949,1187018,1187027-1187028,1187381,1187753,1187755,1187775,1187801,1187806,1187809,1187827,1188301,1188303-1188305,1188399,1188822,1188930-1188931,1189116,1189129,1189183,1189240,1189256,1189386,1189413-1189414,1189477,1189685,1189805,1189857,1189864,1189882,1190034,1190185,1190279,1190339
 ,1190371,1190388-1190389,1190474,1190481,1194915,1195222-1195223,1195531,1195899,1195905,1195943,1195949,1195953,1195955,1195965,1195968,1196175,1196212,1196223,1196304-1196305,1196735,1196825,1196827,1197158,1197261,1197263,1197299-1197300,1197305,1197339-1197340,1197343,1197382,1197386-1197387,1197480,1197578,1198497,1198528,1198552,1198602,1198604,1198607,1198622,1198640,1198696,1198707,1199418,1199432,1199436,1199513,1199529,1199980,1199996,1200056,1200089,1200106-1200107,1200263,1200316,1200320,1200398-1200399,1200445-1200446,1200555,1200627,1200696,1200725,1200937,1200941,1201069,1201087,1201180,1201235-1201237,1201508,1201521,1201542,1201545-1201546,1201548,1201555-1201556,1201568,1201576,1201608,1201921-1201922,1201931,1202035,1202039,1202271,1202565,1202578,1202705,1202828,1202860,1203047-1203052,1203078,1203091,1203253,1203278,1204182,1204856,1204867,1204936,1204938,1204982,1205033,1205065,1205082,1205097,1205112,1206200,1207692,1208046,1208073,1208096,1208114,1208
 145,1208772,1209194,1209277-1209278,1209686-1209731,1210894,1212091,1212095,1212099,1212118,1213469,1213906,1214853,1214855,1214864,1215115,1215118-1215119,1215121,1220293,1220295,1221038,1221842,1222189,1222201,1222276,1222300,1222690,1222850,1222852,1222855,1224607,1224617,1224648-1224652,1224657,1224662-1224663,1224682,1224801,1224910,1225000,1225219,1225343,1225465,1225627,1225629,1225634,1226069,1226158-1226159,1226177,1226196,1226214-1226215,1226385,1226394,1226500,1226537-1226538,1226546,1226551,1226975,1228196,1228360,1228376,1228724,1228908,1228918,1228920,1228922,1228929,1228969,1229307,1229536,1229549,1229724,1229726-1229731,1229997,1230539,1230711,1230729,1230762-1230763,1230765,1230955,1230957,1231285,1231290,1231308,1231310,1231337,1231460-1231461,1231542-1231543,1231546-1231547,1231620-1231621,1231624-1231625,1231630,1231654-1231655,1231738,1231740,1231762-1231763,1231856,1231886,1231923,1231947,1232345,1232368,1232380,1232447,1232760,1232813,1232842-1232843,1
 232869,1233413,1233423,1233426,1234143,1234567,1235207,1236906-1236907,1236914,1237146,1237154-1237156,1237332,1237334,1237425,1237427,1237604,1237975,1237981,1237985,1238070,1238073,1239024,1239048,1239050,1239060,1239135,1239483,1239485,1240101,1240106,1240109,1240112,1240114,1240116,1240118,1240121,1240329,1240697,1240795,1240821,1240842,1240857,1241087,1241160,1241908-1241909,1241982,1242099,1242110,1242371,1242434,1242495,1242947,1243034,1243038,1244302,1244511,1244567,1244718-1244719,1244935-1244938,1245274,1245449,1245849,1290875,1292334,1292338,1292345-1292347,1293155,1293831-1293832,1295998,1297014-1297015,1297017,1297158,1297177,1297202,1297209,1297213,1297717,1297722,1297729,1297768,1297778,1297818,1297828,1297979,1297987,1298121,1298140,1298590,1298592,1298628-1298629,1298794,1298983-1298984

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1298986&r1=1298985&r2=1298986&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Fri Mar  9 19:13:18 2012
@@ -27,6 +27,7 @@ import java.io.InputStream;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
@@ -2244,8 +2245,7 @@ public class WebappClassLoader
                     }
 
                     // TimerThread can be stopped safely so treat separately
-                    if (thread.getClass().getName().equals(
-                            "java.util.TimerThread") &&
+                    if (thread.getClass().getName().startsWith("java.util.Timer") &&
                             clearReferencesStopTimerThreads) {
                         clearReferencesStopTimerThread(thread);
                         continue;
@@ -2268,20 +2268,28 @@ public class WebappClassLoader
                     // If the thread has been started via an executor, try
                     // shutting down the executor
                     try {
-                        Field targetField =
-                            thread.getClass().getDeclaredField("target");
-                        targetField.setAccessible(true);
-                        Object target = targetField.get(thread);
-
-                        if (target != null &&
-                                target.getClass().getCanonicalName().equals(
-                                "java.util.concurrent.ThreadPoolExecutor.Worker")) {
-                            Field executorField =
-                                target.getClass().getDeclaredField("this$0");
-                            executorField.setAccessible(true);
-                            Object executor = executorField.get(target);
-                            if (executor instanceof ThreadPoolExecutor) {
-                                ((ThreadPoolExecutor) executor).shutdownNow();
+
+                        Field targetField = null;
+                        try {
+                            targetField = thread.getClass().getDeclaredField("target");
+                        }catch (NoSuchFieldException nfe){
+                            targetField = thread.getClass().getDeclaredField("runnable");
+                        }
+                        if (null != targetField){
+                            targetField.setAccessible(true);
+                            Object target = targetField.get(thread);
+
+                            if (target != null &&
+                                    target.getClass().getCanonicalName() != null
+                                    && target.getClass().getCanonicalName().equals(
+                                    "java.util.concurrent.ThreadPoolExecutor.Worker")) {
+                                Field executorField =
+                                    target.getClass().getDeclaredField("this$0");
+                                executorField.setAccessible(true);
+                                Object executor = executorField.get(target);
+                                if (executor instanceof ThreadPoolExecutor) {
+                                    ((ThreadPoolExecutor) executor).shutdownNow();
+                                }
                             }
                         }
                     } catch (SecurityException e) {
@@ -2350,21 +2358,33 @@ public class WebappClassLoader
         // - queue.clear()
 
         try {
-            Field newTasksMayBeScheduledField =
-                thread.getClass().getDeclaredField("newTasksMayBeScheduled");
-            newTasksMayBeScheduledField.setAccessible(true);
-            Field queueField = thread.getClass().getDeclaredField("queue");
-            queueField.setAccessible(true);
-
-            Object queue = queueField.get(thread);
-
-            Method clearMethod = queue.getClass().getDeclaredMethod("clear");
-            clearMethod.setAccessible(true);
-
-            synchronized(queue) {
-                newTasksMayBeScheduledField.setBoolean(thread, false);
-                clearMethod.invoke(queue);
-                queue.notify();  // In case queue was already empty.
+
+            try {
+                Field newTasksMayBeScheduledField =
+                    thread.getClass().getDeclaredField("newTasksMayBeScheduled");
+                newTasksMayBeScheduledField.setAccessible(true);
+                Field queueField = thread.getClass().getDeclaredField("queue");
+                queueField.setAccessible(true);
+
+                Object queue = queueField.get(thread);
+
+                Method clearMethod = queue.getClass().getDeclaredMethod("clear");
+                clearMethod.setAccessible(true);
+
+                synchronized(queue) {
+                    newTasksMayBeScheduledField.setBoolean(thread, false);
+                    clearMethod.invoke(queue);
+                    queue.notify();  // In case queue was already empty.
+                }
+
+            }catch (NoSuchFieldException nfe){
+                Method cancelMethod = thread.getClass().getDeclaredMethod("cancel");
+                if (null != cancelMethod){
+                    synchronized(thread) {
+                        cancelMethod.setAccessible(true);
+                        cancelMethod.invoke(thread);
+                    }
+                }
             }
 
             log.error(sm.getString("webappClassLoader.warnTimerThread",
@@ -2394,21 +2414,29 @@ public class WebappClassLoader
             inheritableThreadLocalsField.setAccessible(true);
             // Make the underlying array of ThreadLoad.ThreadLocalMap.Entry objects
             // accessible
-            Class<?> tlmClass =
-                Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
+            Class<?> tlmClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
             Field tableField = tlmClass.getDeclaredField("table");
             tableField.setAccessible(true);
+            Method expungeStaleEntriesMethod = tlmClass.getDeclaredMethod("expungeStaleEntries");
+            expungeStaleEntriesMethod.setAccessible(true);
 
             for (int i = 0; i < threads.length; i++) {
                 Object threadLocalMap;
                 if (threads[i] != null) {
+
                     // Clear the first map
                     threadLocalMap = threadLocalsField.get(threads[i]);
-                    checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+                    if (null != threadLocalMap){
+                        expungeStaleEntriesMethod.invoke(threadLocalMap);
+                        checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+                    }
+
                     // Clear the second map
-                    threadLocalMap =
-                        inheritableThreadLocalsField.get(threads[i]);
-                    checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+                    threadLocalMap =inheritableThreadLocalsField.get(threads[i]);
+                    if (null != threadLocalMap){
+                        expungeStaleEntriesMethod.invoke(threadLocalMap);
+                        checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+                    }
                 }
             }
         } catch (SecurityException e) {
@@ -2426,6 +2454,12 @@ public class WebappClassLoader
         } catch (IllegalAccessException e) {
             log.warn(sm.getString("webappClassLoader.checkThreadLocalsForLeaksFail",
                     contextName), e);
+        } catch (InvocationTargetException e) {
+            log.warn(sm.getString("webappClassLoader.checkThreadLocalsForLeaksFail",
+                    contextName), e);
+        } catch (NoSuchMethodException e) {
+            log.warn(sm.getString("webappClassLoader.checkThreadLocalsForLeaksFail",
+                    contextName), e);
         }
     }
 
@@ -2529,7 +2563,7 @@ public class WebappClassLoader
 
         ClassLoader cl = clazz.getClassLoader();
         while (cl != null) {
-            if(cl == this) {
+            if (cl == this) {
                 return true;
             }
             cl = cl.getParent();

Propchange: tomcat/tc7.0.x/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/tc7.0.x/trunk/test/org/apache/catalina/loader/TestWebappClassLoaderThreadLocalMemoryLeak.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1298986&r1=1298985&r2=1298986&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Mar  9 19:13:18 2012
@@ -95,6 +95,11 @@
         MemoryUser but GenericPrincipal into a session when UserDatabaseRealm 
         is used. (kfujino)
       </fix>
+      <add>
+        <bug>52850</bug>: Extend memory leak prevention and detection code to
+        work with IBM as well as Oracle JVMs. Patch provided by Rohit Kelapure.
+        (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org