tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <>
Subject [Tomcat Wiki] Trivial Update of "MemoryLeakProtection" by SylvainLaurent
Date Tue, 16 Mar 2010 22:42:24 GMT
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.


  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
+ '''Caution:''' This diagnosis calls {{{System.gc()}}} which may not be desirable in production
  = 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}}}
+ 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:
For additional commands, e-mail:

View raw message