Jumat, 20 Juni 2014

ThreadLocal Memory Leak in Java web application - Tomcat




ThreadLocal variables are infamous for creating memory leaks. A memory
leak in Java is amount of memory hold by object which are not in use and should
have been garbage collected, but because of unintended strong references, they
still live in Java heap space. There are many
ways memory leak can be caused in Java but when this memory leak is caused due
to
ThreadLocal variable, it’s refereed as ThreadLocal memory
leak. In our last post about ThreadLocal variable, we have seen How ThreadLocal variable can make
SimpleDateFormat thread-safe
and also raised point that in managed
environment like J2EE application server or web server like
Tomcat, Jetty, WebSphere or Weblogic use of ThreadLocal should be
avoided. In this post we will go little deep and find out How
ThreadLocal
variables creates
memory leak in Java web application, much like we have seen How to fix PermGen memory leak in Tomcat
.
If you are not familiar with
ThreadLocal variables
I suggest to go through my previous post. Before going into detail let's recap
How
ThreadLocal class works in Java.







How
ThreadLocal works in Java :


ThreadLocal memory leak in Java web application in tomcatThreadLocal in Java is a mechanism to provide separate copy of shared
object to every Thread. So that they no longer shared between multiple Threads
and remain thread-safe.
ThreadLocal variables
are stored in a special map called
ThreadLocalMap which is
designed to hold thread local objects, it uses
WeakReferences for keys.
Since every Thread has strong reference to
there copy of
ThreadLocal variables, they are not garbage
collected until Thread is Alive and this is what creates memory leak in a
typical J2EE web application. This is explained in detail in next section “How ThreadLocal variable creates memory
leak in Java”
.





How ThreadLocal creates memory leak in Java



In web server and application server
like
Tomcat or WebLogic, web-app is loaded by a different
ClassLoader than
which is used
by Server itself. This ClassLoader loads and unloads classes from web
application. Web servers also maintains
ThreadPool, which is
collection of worker thread, to server HTTP requests. Now if one of the Servlet
or any other Java class from web application creates a
ThreadLocal variable
during request processing and doesn't remove it after that, copy of that Object will remain with worker
Thread and since life-span of worker Thread is more than web app itself,
it will prevent the object and
ClassLoader, which
uploaded the web app, from being garbage collected. This will create a memory
leak in Server. Now if you do this couple of time you may see java.lang.OutOfMemoryError: PermGen space
.
Now this brings an important question, 
is it possible to to use
ThreadLocal variable
safely in a managed environment?  Answer
is Yes,, but that requires a careful usage of
ThreadLocal variable and
making sure to remove the object from ThreadLocal once done.





How to
use ThreadLocal safely in Java Web application


Many people use Filters to initialize and remove ThreadLocal variables.
You can initialize
ThreadLocal in filter, put some expensive
object as ThreadLocal and once request has been processed remove it from
ThreadLocal as shown in below example:






public void
doFilter(ServeletRequest request,
ServletResponse){

        try{



          //set
ThreadLocal variable


        chain.doFilter(request, response)



        }finally{

          //remove
threadLocal variable.


        }

}






That’s all on How ThreadLocal variable creates memory leak in Java. Having
said that, If not necessary or You can manage without
ThreadLocal variable
than it’s best to avoid using ThreadLocal in managed environments like J2EE web
and application servers.



























Source:http://javarevisited.blogspot.com/2013/01/threadlocal-memory-leak-in-java-web.html

Tidak ada komentar:

Posting Komentar