Re: Memory Leak caused by ThreadLocalMap - The suspect is com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet

265 views
Skip to first unread message

Shawn Brown

unread,
Nov 27, 2012, 6:03:51 AM11/27/12
to google-we...@googlegroups.com


The current implementation of com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet uses two instances of ThreadLocal to wrap the HttpServletRequest and HttpServiceResponse objects. (both are not static; couldn't see any calls to remove; "this" is in the sychronized block - couple of things that triggered my suspicions).

Did anybody faced similar issues?

Don't think so but it concerned me so I took a look ... seems ok but...

Every doPost it will call

if (perThreadRequest == null) {
      perThreadRequest = new ThreadLocal<HttpServletRequest>();
    }
if (perThreadResponse == null) {
      perThreadResponse = new ThreadLocal<HttpServletResponse>();
    } So that would be one instance of each per servlet right!?! Also per doPost it calls: try {
    perThreadRequest.set(request);
    perThreadResponse.set(response);
 

      processPost(request, response);

...     } finally {
      // null the thread-locals to avoid holding request/response
      //
      perThreadRequest.set(null);
      perThreadResponse.set(null); } So that should clear the response, request right!?! I can't see an issue with AbstractRemoteServiceServlet but ... am I missing something?

Well OK I don't understand why the call is perThreadRequest.set(null) and NOT .remove()

remove() 
          Removes the current thread's value for this thread-local variable

set(T value) 
          Sets the current thread's copy of this thread-local variable to the specified value.

  Are the 400.000 entries null and if so is that taking memory???

jhulford

unread,
Nov 27, 2012, 9:48:59 AM11/27/12
to google-we...@googlegroups.com
Look at the ThreadLocal source and you'll see it stores all your ThreadLocal objects in what basically amounts to hash map of weak references.  The reason set(null) is called is that since it's assumed that Servlet instances/threads are being re-used to handle incoming requests, since that's how containers are supposed to do it, you can avoid the bit of overhead of fully removing the whole thread id key and map value done in remove() by just nulling out the thread local value associated with the thread id.

Since ThreadLocal uses a weak reference for the keys of its internal ThreadLocalMap too, even if your servlet threads are eventually killed off and replaced by new threads they and their thread locals should be able to be garbage collected.

I would see if you dig deeper and see what that thread local map is actually storing (jmap / jhat are your friends), perhaps your persistence or injection framework is leaving behind thread locals, I don't think it's GWT's remote service servlet though.
Reply all
Reply to author
Forward
0 new messages