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

Reply via email to