From 17eb29aafdbd9a98880667620eb269c931c3e9b7 Mon Sep 17 00:00:00 2001 From: markt Date: Fri, 25 Jun 2010 07:53:24 +0000 Subject: [PATCH] Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49414 Try to differentiate between request threads and threads started by applications git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@957830 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/loader/LocalStrings.properties | 3 +- .../apache/catalina/loader/WebappClassLoader.java | 39 ++++++++++++++++++++-- webapps/docs/config/context.xml | 5 ++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/java/org/apache/catalina/loader/LocalStrings.properties b/java/org/apache/catalina/loader/LocalStrings.properties index 3d02dbe32..18c1a0859 100644 --- a/java/org/apache/catalina/loader/LocalStrings.properties +++ b/java/org/apache/catalina/loader/LocalStrings.properties @@ -46,7 +46,8 @@ webappClassLoader.clearThreadLocalFail=Failed to clear ThreadLocal references fo webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for web application [{1}] webappClassLoader.stopTimerThreadFail=Failed to terminate TimerThread named [{0}] for web application [{1}] webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0} -webappClassLoader.warnThread=The web application [{0}] appears to have started a thread named [{1}] but has failed to stop it. This is very likely to create a memory leak. +webappClassLoader.warnRequestThread=The web application [{0}] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. +webappClassLoader.warnThread=The web application [{0}] appears to have started a thread named [{1}] but has failed to stop it. This is very likely to create a memory leak. webappClassLoader.warnTimerThread=The web application [{0}] appears to have started a TimerThread named [{1}] via the java.util.Timer API but has failed to stop it. To prevent a memory leak, the timer (and hence the associated thread) has been forcibly canceled. webappClassLoader.wrongVersion=(unable to load class {0}) webappLoader.addRepository=Adding repository {0} diff --git a/java/org/apache/catalina/loader/WebappClassLoader.java b/java/org/apache/catalina/loader/WebappClassLoader.java index ccd92054a..13e419bcc 100644 --- a/java/org/apache/catalina/loader/WebappClassLoader.java +++ b/java/org/apache/catalina/loader/WebappClassLoader.java @@ -2184,8 +2184,13 @@ public class WebappClassLoader continue; } - log.error(sm.getString("webappClassLoader.warnThread", - contextName, thread.getName())); + if (isRequestThread(thread)) { + log.error(sm.getString("webappClassLoader.warnRequestThread", + contextName, thread.getName())); + } else { + log.error(sm.getString("webappClassLoader.warnThread", + contextName, thread.getName())); + } // Don't try an stop the threads unless explicitly // configured to do so @@ -2241,6 +2246,36 @@ public class WebappClassLoader } + /* + * Look at a threads stack trace to see if it is a request thread or not. It + * isn't perfect, but it should be good-enough for most cases. + */ + private boolean isRequestThread(Thread thread) { + + StackTraceElement[] elements = thread.getStackTrace(); + + if (elements == null || elements.length == 0) { + // Must have stopped already. Too late to ignore it. Assume not a + // request processing thread. + return false; + } + + // Step through the methods in reverse order looking for a + // CoyoteAdapter.service() call. All requests will have this unless + // Tomcat has been heavily modified - in which case there isn't much we + // can do. + for (int i = 0; i < elements.length; i++) { + StackTraceElement element = elements[elements.length - (i+1)]; + if ("org.apache.catalina.connector.CoyoteAdapter".equals( + element.getClassName()) && + "service".equals(element.getMethodName())) { + return true; + } + } + return false; + } + + private void clearReferencesStopTimerThread(Thread thread) { // Need to get references to: diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml index 729e0332f..302e92615 100644 --- a/webapps/docs/config/context.xml +++ b/webapps/docs/config/context.xml @@ -465,9 +465,8 @@ -

Amount of ms that the container will wait for servlets to unload. - If not specified, the default value of the flag is 2000 - ms.

+

Number of ms that the container will wait for servlets to unload. + If not specified, the default value is 2000 ms.

-- 2.11.0