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=1&rev2=2

--------------------------------------------------

  This page tries to list them, and shows the situations where leaks can be 
detected and fixed.
  
  = Diagnose a classloader leak upon request =
+ Starting with tomcat 6.0.25, the manager webapp has a new "Find Leaks" 
button. When triggered, it displays a list of webapps (their context path) that 
have been stopped (this includes undeployed and redeployed ones) but whose 
classloader failed to be GCed.
+ 
+ If a leaking webapp is redeployed several times, it will appear as many times 
as it actually leaked.
+ 
+ '''Caution:''' This diagnosis calls {{{System.gc()}}} which may not be 
desirable in production environments.
  
  = Different types of leaks that Tomcat can detect (or not) =
  
+ When a webapp execution is stopped (this encompassed redeploy and undeploy), 
tomcat tries to detect and fix leaks.
+ 
+ Starting with tomcat 6.0.24, messages are logged to indicate the kind of leak 
that was detected.
+ 
  == ThreadLocal leaks ==
+ Classloader leaks because of uncleaned {{{ThreadLocal}}} variables are quite 
common.
+ Depending on the use cases, they can be detected or not.
  
  === Custom ThreadLocal class ===
+ Suppose we have the following 3 classes in our webapp :
+ 
+ {{{
+ public class MyCounter {
+       private int count = 0;
+ 
+       public void increment() {
+               count++;
+       }
+ 
+       public int getCount() {
+               return count;
+       }
+ }
+ 
+ public class MyThreadLocal extends ThreadLocal<MyCounter> {
+ }
+ 
+ public class LeakingServlet extends HttpServlet {
+       private static MyThreadLocal myThreadLocal = new MyThreadLocal();
+ 
+       protected void doGet(HttpServletRequest request,
+                       HttpServletResponse response) throws ServletException, 
IOException {
+ 
+               MyCounter counter = myThreadLocal.get();
+               if (counter == null) {
+                       counter = new MyCounter();
+                       myThreadLocal.set(counter);
+               }
+ 
+               response.getWriter().println(
+                               "The current thread served this servlet " + 
counter.getCount()
+                                               + " times");
+               counter.increment();
+       }
+ }
+ }}}
+ 
+ If the {{{LeakingServlet}}} is invoked at least once and the Thread that 
served it is not stopped, then we created a classloader leak !
+ 
+ The leak is caused because we have a custom class for the {{{ThreadLocal}}} 
instance, and also a custom class for the value bound to the Thread. Actually 
the important thing is that both classes were loaded by the webapp classloader.
+ 
+ Hopefully tomcat 6.0.24 can detect the leak when the application is stopped: 
each Thread in the JVM is examined, and the internal structures of the Thread 
and {{{ThreadLocal}}} classes are introspected to see if either the 
{{{ThreadLocal}}} instance of the value bound to it were loaded by the 
{{{WebAppClassLoader}}} of the application being stopped.
+ 
+ In this particular case, the leak is detected, a message is logged and 
internal structures of the JDK ({{{ThreadLocalMap}}}) are modified to remove 
the reference to the {{{ThreadLocal}}} instance.
+ 
+ TODO: add an example of log
+ 
+ Note: this particular leak was actually already cured by previous versions of 
tomcat, because static references of classes loaded by the webappclassloader 
are nullified (see later).
  
  === Webapp class instance as ThreadLocal value ===
  

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

Reply via email to