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