Dear Wiki user, You have subscribed to a wiki page or wiki category on "Tomcat Wiki" for change notification.
The "MemoryLeakProtection" page has been changed by SylvainLaurent. http://wiki.apache.org/tomcat/MemoryLeakProtection?action=diff&rev1=5&rev2=6 -------------------------------------------------- Tomcat 6.0.24 "speeds up" the removal of stale entries (and thus fixes the pseudo-leak), by calling {{{expungeStaleEntries()}}} for each thread that has some stale entries. == Threads ContextClassLoader == + === Threads spawned by webapps === + + If a webapp creates a thread, by default its context classloader is set to the one of the parent thread (the thread that created the new thread). + In a webapp, this parent thread is one of tomcat worker threads, whose context classloader is set to the webapp classloader when it executes webapp code. + + Furthermore, the spawned thread may be executing (or blocked in) some code that involves classes loaded by the webapp, thus preventing the webapp classloader from being collected. + + So, if the spawned thread is not properly terminated when the application is stopped, the webapp classloader will leak because of the strong reference held by the spawned thread. + + Example : + {{{ + public class LeakingServlet extends HttpServlet { + private Thread leakingThread; + + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + if (leakingThread == null) { + synchronized (this) { + if (leakingThread == null) { + leakingThread = new Thread("leakingThread") { + + @Override + public void run() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }; + leakingThread.setDaemon(true); + //leakingThread.setContextClassLoader(null); + leakingThread.start(); + } + } + } + response.getWriter().println("Hello world!"); + } + } + }}} + + Here, when the app is stopped, the webapp classloader is still referenced by the spawned thread both through its context classloader and its current call stack (the anonymous Thread subclass is loaded by the webapp classloader). + + When stopping an application, tomcat checks the context classloader of every Thread, and if it is the same as the app being stopped, it logs the following message : + {{{ + Mar 18, 2010 11:13:07 PM org.apache.catalina.core.ApplicationContext log + INFO: HTMLManager: stop: Stopping web application at '/testWeb' + Mar 18, 2010 11:13:07 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads + SEVERE: A web application appears to have started a thread named [leakingThread] but has failed to stop it. This is very likely to create a memory leak. + }}} + + Now, if we uncomment the line {{{leakingThread.setContextClassLoader(null);}}} in the above example, tomcat (6.0.24) no longer detect the leak when the application is stopped because the spawned thread context classloader is no longer the webapp's. (the "Find leaks" feature in the manager will report it though) + + === Threads spawned by classes loaded by the common classloader === + + TODO : example with the Evictor thread of dbcp + === Threads spawned by JRE classes === - === Threads spawned by classes loaded by the common classloader === - === Threads spawned by webapps === == Child classloaders == @@ -230, +288 @@ == RMI target == = Summary matrix = + ||Leak type||Detected by tomcat||Fixed by tomcat||Possible enhancements|| ---- == References == - [[http://java.dzone.com/articles/memory-leak-protection-tomcat|Mark Thomas interview on DZone]] + * [[http://java.dzone.com/articles/memory-leak-protection-tomcat|Mark Thomas interview on DZone]] + * [[http://www.eclipse.org/mat|Eclipse Memory Analysis Tool]] Related issues * [[https://issues.apache.org/bugzilla/show_bug.cgi?id=48837|48837]] - Memory leaks protection does not cure leaks triggered by JSP pages code --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org