tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
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.
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message