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] Update of "MemoryLeakProtection" by SylvainLaurent
Date Wed, 17 Mar 2010 22:28:58 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=4&rev2=5

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

  
  == ThreadLocal pseudo-leak ==
  
+ Suppose we have the same {{{MyCounter}}} class as above (in the webapp) and the following
servlet :
+ {{{
+ public class LeakingServlet extends HttpServlet {
+ 	private ThreadLocal<MyCounter> myThreadLocal = new ThreadLocal<MyCounter>();
+ 
+ 	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();
+ 	}
+ 
+ 	@Override
+ 	public void destroy() {
+ 		super.destroy();
+ 		// normally not needed, just to make my point
+ 		myThreadLocal = null;
+ 	}
+ }
+ }}}
+ 
+ Notice that the {{{ThreadLocal}}} instance is referenced through an instance variable, not
a static one.
+ 
+ Sun's implementation of {{{ThreadLocal}}} (and {{{WeakHashMap}}}) too is such that {{{ThreadLocalMap}}}
entries whose key is GCed are not immediately removed.
+ (The key is a weak reference to the {{{ThreadLocal}}} instance, see {{{java.lang.ThreadLocal.ThreadLocalMap.Entry<T>
in JDK 5/6}}}. And there's no daemon thread waiting on a {{{ReferenceQueue}}}). Instead, it's
only during subsequent uses of {{{ThreadLocal}}} features that each Thread removes the abandoned
{{{ThreadLocalMap.Entry}}} entries (see {{{ThreadLocalMap.expungeStaleEntries()}}}.
+ 
+ If many threads were used to serve our leaking webapp, but after we stop it only a couple
of threads are enough to serve other webapps, one could have some threads that are no longer
used, waiting for some work. Since those threads are blocked, they have no interaction with
their {{{ThreadLocalMap}}} (i.e. there's no {{{ThreadLocal}}} value bound to them or removed),
so that there's no opportunity to {{{expungeStaleEntries()}}}.
+ 
+ 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 JRE classes ===
  === Threads spawned by classes loaded by the common classloader ===

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


Mime
View raw message