Quantcast

Threadlocals and memory leaks in J2EE

classic Classic list List threaded Threaded
50 messages Options
123
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Threadlocals and memory leaks in J2EE

Unmesh joshi

Hi,
 
Threadlocals are used in J2EE application servers to keep track of transaction context and security context. I was thinking of using it to pass execution context (which involves some user login and other context information) around in web application which involves servlets and other server side classes. (As discussed at http://www.theserverside.com/news/thread.tss?thread_id=41473).
I remember reading somewhere that Threadlocals can cause memory leaks if Threads are getting reused through thread pools. (Which is the case in J2EE application servers).
What way can Threadlocal cause memory leak? How Threadlocals behave with Classloaderes in J2EE? In what cases thread local usage is not recommended?
 
Thanks,
Unmesh


Get the new Windows Live Messenger! Try it!
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Endre Stølsvik-6
Unmesh joshi wrote:

>
> Hi,
>  
> Threadlocals are used in J2EE application servers to keep track of
> transaction context and security context. I was thinking of using it to
> pass execution context (which involves some user login and other context
> information) around in web application which involves servlets and other
> server side classes. (As discussed at
> http://www.theserverside.com/news/thread.tss?thread_id=41473).
> I remember reading somewhere that Threadlocals can cause memory leaks if
> Threads are getting reused through thread pools. (Which is the case in
> J2EE application servers).
> What way can Threadlocal cause memory leak? How Threadlocals behave with
> Classloaderes in J2EE? In what cases thread local usage is not recommended?

Here's your fix of your information needs!

Vote for this! NOW!
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6254531

Technical low-down on the problem, and a fix:
http://www.jroller.com/tackline/entry/fixing_threadlocal

.. a quite involved "drop in ThreadLocal replacement" workaround:
http://www.jroller.com/tackline/entry/working_around_the_threadlocal_leak
   The problem here is that since ThreadLocals might be used in third
party libraries, you quite possibly end up not being able to replace
their usages..

(Those links all actually link to each other.. And if you follow links
further, you'll get even more info..)

In what use cases: when you reuse thread(pools) and at the same time
change class loaders to implement "reload" functionality. With that
usage pattern, you will often have the old, reused threads hang onto
hard references to all the old application instance's ThreadLocal
values, and thereby also that instance's classes, not permitting these
to be garbage collected.

So - it basically only happens for "containers" of different sorts, for
example (and in particular!) Tomcat.
  (The Tomcat guys could easily have fixed it on their side, by either
hacking into the innards of Thread (by introspection) and "wash" their
ThreadLocal references, or make a brand new thread pool when any webapp
is reloaded, letting the old threads die. However, Tomcat seems
dictatorially lead by this nice chap from JBoss that instantly WONTFIXes
bugs he personally isn't affected by, without considering the
implications for others.)

Kind regards,
Endre.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

alarmnummer
In reply to this post by Unmesh joshi
My guess is that the memory leak is a ThreadLocal that is not properly
cleaned, so the garbage collector doesn't collect the garbage (from a
garbage collector point of view it still is a valid object reference).

On 10/8/07, Unmesh joshi <[hidden email]> wrote:

>
>
> Hi,
>
>  Threadlocals are used in J2EE application servers to keep track of
> transaction context and security context. I was thinking of using it to pass
> execution context (which involves some user login and other context
> information) around in web application which involves servlets and other
> server side classes. (As discussed at
> http://www.theserverside.com/news/thread.tss?thread_id=41473).
>  I remember reading somewhere that Threadlocals can cause memory leaks if
> Threads are getting reused through thread pools. (Which is the case in J2EE
> application servers).
>  What way can Threadlocal cause memory leak? How Threadlocals behave with
> Classloaderes in J2EE? In what cases thread local usage is not recommended?
>
>  Thanks,
>  Unmesh
>
> ________________________________
> Get the new Windows Live Messenger! Try it!
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Taras Tielkes
Peter Veentjer wrote:
> My guess is that the memory leak is a ThreadLocal that is not properly
> cleaned, so the garbage collector doesn't collect the garbage (from a
> garbage collector point of view it still is a valid object reference).

ThreadLocal doesn't perform eager clean-up in the first place.

IIRC, there's a 'GoodCitizedThreadLocal' planned for 1.7. It has been
discussed on this list a couple of times - I'm not sure what the current
status is.

But there are tens of other ways to shoot yourself in the foot with
ThreadLocals. For example: a webapp generates an image using Java2D, and
sends it to the browser, encoded as PNG.

If it's the first in VM to use Java2D, the contextClassLoader will be
copied to the Disposer thread started by the initializing Java2D
subsystem. Since that one will only exit at VM shutdown, the webapp will
never be unloaded.

To be fair, above example is from the 'once-during-VM-lifetime' category
of ClassLoader leaks. However, it shares that catagory with many
siblings - the util.logging subsystem exhibits an almost identical problem.

-tt

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Larry Riedel
In reply to this post by Unmesh joshi

I hope I would not be anathema for saying it... my tendency
would be not to recommend using java.lang.ThreadLocal unless
there is no apparent (relatively clean) alternative (I still
think it would have been nice if Thread IDs could not be
reused).  I like the concept of thread-local variables,
if they were more a native part of the language and JVM.
Even so, I wonder how well that concept meshes with thread
pools where there will be, for example, different threads
representing the same "user" at different times.


Larry

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

David Holmes-3
Larry,

I wouldn't say that exactly but I would point out that this is a
THREAD-local. A ThreadLocal variable is managed on a per-thread basis, by
the Thread. It disappears when the Thread terminates, or when the Thread
explicitly clears it.

The problem - as per the eval of that bug report referenced - is that people
use ThreadLocal as a mechanism to implement something that is
"context"-local ( where "context" can be different things). The life-time of
a "context" is not tied to the lifetime of a Thread and hence you have a
mismatch there; but also the "identity" of a "context" is not necessarily
constrained to the same Thread, and that is an even worse mismatch.

People are using ThreadLocal for things that are not thread-local, in the
sense of how ThreadLocal was designed. Hence the problems. Changing
ThreadLocal might help alleviate some of the problems, but to me that's
somewhat missing the real problem. The applications that reuse threads in
different contexts should be the ones ensuring the threads are correctly
"configured", with respect to ThreadLocal, when they switch "contexts". For
the future we should look at how a ContextLocal variable might be defined.

Just my 2c.

Cheers,
David Holmes

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of Larry
> Riedel
> Sent: Tuesday, 9 October 2007 7:54 AM
> To: [hidden email]
> Subject: Re: [concurrency-interest] Threadlocals and memory leaks in
> J2EE
>
>
>
> I hope I would not be anathema for saying it... my tendency
> would be not to recommend using java.lang.ThreadLocal unless
> there is no apparent (relatively clean) alternative (I still
> think it would have been nice if Thread IDs could not be
> reused).  I like the concept of thread-local variables,
> if they were more a native part of the language and JVM.
> Even so, I wonder how well that concept meshes with thread
> pools where there will be, for example, different threads
> representing the same "user" at different times.
>
>
> Larry
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Larry Riedel

> People are using ThreadLocal for things that are not thread-local,
> in the sense of how ThreadLocal was designed. Hence the
> problems. Changing ThreadLocal might help alleviate some of the
> problems, but to me that's somewhat missing the real problem.

I may not have been paying enough attention, but it was
not clear to me what practical problem the implementation
of java.lang.ThreadLocal that appeared in JDK 1.2 was
designed to solve.  At the time I had been hoping for
something very fast and seamless, implemented as some highly
optimized/tuned/platform-specific code inside the JVM,
rather than some Java code that does a lookup in a hash
table where the Thread object is a key, which is something
I as an application developer could do myself.  In other
words I had been hoping it was going to be provided as a
performance boost for applications that had already been
tuned as well as they could at the Java source code level,
and could get an extra boost by using per-Thread objects
to reduce the overhead in the JVM.  Performance for Java
applications was a much bigger problem back then.  In the
context of ClassLoader and ProtectionDomain and all the
stuff that goes along with the concept of a JVM as an
operating system running untrusted applications... I can see
ThreadLocal in that context as a security related feature
for some clever code to leverage.  It is not apparent to
me there are many situations for ordinary application
programmers where using ThreadLocal would be a better idea
than just using some sort of application level mapping.


Larry

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

David Holmes-3
Hi Larry,

> I may not have been paying enough attention, but it was
> not clear to me what practical problem the implementation
> of java.lang.ThreadLocal that appeared in JDK 1.2 was
> designed to solve.

Disclaimer: this is my opinion only, I wasn't involved in the design or
implementation of ThreadLocal.

The "implementation" wasn't trying to solve any problem. The API was
designed to provide a way to associate objects with threads. A ThreadLocal
is a substitute for a new field in Thread - necessary because the code that
wants to carry this information around often doesn't have the ability to
control the actual thread creation of the classes used therein.
ThreadLocal's are per-thread-global-variables. They are typically used when
the application can't customize the threads involved, and where passing the
"context" via the call-chain is just too ugly.

In my view that is all ThreadLocal is - a substitute for a field. If you
couldn't solve your problem by adding a field to Thread then ThreadLocal
isn't a solution for you either.

Yes application code could provide this sort of API itself, but why have
everyone reinvent the wheel - this is what libraries are for, so we have
ThreadLocal.

How ThreadLocal was implemented was (not to be trite) an implementation
issue. The original value->Thread mapping had problems with locking and
associated overhead. The inverted Thread->value mapping is much better. This
wasn't expected to be a factor on the critical-path of reasonable
applications.

Could this have been implemented at the VM level using platform specific
thread-local code? Perhaps - not sure what Windows supports. But if you can
get a reasonable solution at the Java level you try to avoid platform
specific code in the VM. Besides, how do OS level thread-locals work? Aren't
they just a lookup "map" too?

Cheers,
David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Aaron Silinskas
In reply to this post by Larry Riedel
Larry Riedel wrote:

>> People are using ThreadLocal for things that are not thread-local,
>> in the sense of how ThreadLocal was designed. Hence the
>> problems. Changing ThreadLocal might help alleviate some of the
>> problems, but to me that's somewhat missing the real problem.
>>    
>
> I may not have been paying enough attention, but it was
> not clear to me what practical problem the implementation
> of java.lang.ThreadLocal that appeared in JDK 1.2 was
> designed to solve.  At the time I had been hoping for
> something very fast and seamless, implemented as some highly
> optimized/tuned/platform-specific code inside the JVM,
> rather than some Java code that does a lookup in a hash
> table where the Thread object is a key, which is something
> I as an application developer could do myself.  In other
> words I had been hoping it was going to be provided as a
> performance boost for applications that had already been
> tuned as well as they could at the Java source code level,
> and could get an extra boost by using per-Thread objects
> to reduce the overhead in the JVM.  Performance for Java
> applications was a much bigger problem back then.  In the
> context of ClassLoader and ProtectionDomain and all the
> stuff that goes along with the concept of a JVM as an
> operating system running untrusted applications... I can see
> ThreadLocal in that context as a security related feature
> for some clever code to leverage.  It is not apparent to
> me there are many situations for ordinary application
> programmers where using ThreadLocal would be a better idea
> than just using some sort of application level mapping.
>
>
> Larry
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>  
Hi Larry,
  I've used ThreadLocals to cache SimpleDateFormat objects when a
relatively small number of threads (pool of 10) used them heavily. I'm
not sure if it would be considered a "good" or "bad" thing, but it was a
quick way to get rid of the contention of a synchronized singleton
without having to create many new SimpleDateFormat objects. I thought I
would throw it out there as an example, and to sanity-check the approach.

Thanks,
Aaron
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Larry Riedel
In reply to this post by David Holmes-3

> The "implementation" wasn't trying to solve any problem. [...] In
> my view that is all ThreadLocal is - a substitute for a field. If
> you couldn't solve your problem by adding a field to Thread then
> ThreadLocal isn't a solution for you either. [...] Yes application
> code could provide this sort of API itself, but why have everyone
> reinvent the wheel - this is what libraries are for, so we have
> ThreadLocal. [...] How ThreadLocal was implemented was (not to
> be trite) an implementation issue. [...] Could this have been
> implemented at the VM level using platform specific thread-local
> code? Perhaps [...] But if you can get a reasonable solution at
> the Java level you try to avoid platform specific code in the VM.

My hope was that performance improvement was a major motivation
behind the introduction of ThreadLocal; if that is postulated,
then I think it follows that efficiency of the implementation
is a sine qua non.  My hope at the time was that ThreadLocal was
going to be similar to something like in the 1997 paper from Doug
Schmidt etc all about "Thread Specific Storage", "An Object
Behavioral Pattern for Accessing per-Thread State Efficiently".
(http://www.cs.wustl.edu/~schmidt/PDF/TSS-pattern.pdf)

Excerpts:

    1 Intent
    Allows multiple threads to use one logically global access
    point to retrieve thread-specific data without incurring
    locking overhead for each access.
    [...]
    This pattern resolves the following forces:
    Efficiency:
        Thread-specific storage allows sequential methods within a
        thread to access thread-specific objects atomically without
        incurring locking overhead for each access.
    Simplify application programming:
        Thread-specific storage is simple for application programmers
        to use because system developers can make the use of
        thread-specific storage completely transparent at the
        source-code level via data abstraction or macros.
    Highly portable:
        Thread-specific storage is available on most multi-threaded
        OS platforms and can be implemented conveniently on platforms
        (such as VxWorks) that lack it.
   Therefore, regardless of whether an application runs in a single
   thread or multiple threads, there should be no additional overhead
   incurred and no changes to the code required to use the
   Thread-Specific Storage pattern.

I think within that context it might be more clear why I
was hoping for ThreadLocal to provide something which had
efficiency as a major motivation.  I also think the "ELF
Handling For Thread-Local Storage" document from Ulrich
Drepper helps give an indication of the significance of
efficiency when "thread-local" storage is discussed.
(http://people.redhat.com/drepper/tls.pdf)


Larry

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

David Holmes-3
Larry Riedel writes:
> My hope was that performance improvement was a major motivation
> behind the introduction of ThreadLocal;

Performance improvement over what? An application specific version of
ThreadLocal? Or something else? I'm not clear what your baseline is here.

I think the API was created to meet a given functional need ie. as Doug
Schmidt wrote:

>     Allows multiple threads to use one logically global access
>     point to retrieve thread-specific data

The original implementation obviously didn't meet Doug Schmidt's efficiency
criteria of "without incurring locking overhead". But the later
implementation addressed that.

> I think within that context it might be more clear why I
> was hoping for ThreadLocal to provide something which had
> efficiency as a major motivation.  I also think the "ELF
> Handling For Thread-Local Storage" document from Ulrich
> Drepper helps give an indication of the significance of
> efficiency when "thread-local" storage is discussed.
> (http://people.redhat.com/drepper/tls.pdf)

Yeah that's interesting stuff - how you would like to do TLS "properly" with
language level integration, not just an API to a look-up table.

Cheers,
David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Joshua Bloch-2
In reply to this post by Larry Riedel
Folks,
 
This thread is littered with misinformation.  Java's ThreadLocal implementation is very, very fast.  It has been completely re-written several times, getting faster each time.  (Props to Doug Lea.) Larry Riedel's description ("some Java code that does a lookup in a hashtable where the Thread object is a key, which is something I as an application developer could do myself.") is wrong on two counts: Only the 1.2 implementation, which was a stopgap, was implemented as per-ThreadLocal map from thread to value.  And practically all application programmers could not "do it themselves." I suggested adding thread locals to the platform only after I saw the fourth broken implementation out of four independent attempts.  Without naming names, these implementations were written by elite systems programmers.
 
There is nothing inherently wrong with thread locals: They do not cause memory leaks. They are not slow. They are more local than their non-thread-local counterparts (i.e., they have better information hiding properties).  They can be misused, of course, but so can most other programming tools.
 
Whether thread locals are in the language or the libraries is largely a matter of syntax.  In '97 I proposed adding thread locals to the language (the threadlocal modifier), but there was insufficient support for this, so I wrote the ThreadLocal API that we now use.
 
Larry says "It is not apparent to me there are many situations for ordinary application programmers where using ThreadLocal would be a better idea than just using some sort of application level mapping."  I am flabbergasted.  What makes Larry think that Joe Programmer's ThreadLocal implementation will be better than the one that Doug and I wrote and carefully optimized? It most certainly will not.
 
There are many compelling uses for thread locals.  Here are a few off the top of my head:
 
(1) Genuine per-thread context, such as user id or transaction id.  Works great.  Easy to clean up when the thread exits the scope.  No leaks.
 
(2) Per-thread instances for performance.  Aaron's SimpleDateFormat example (above) is one example of this pattern.
 
(3) "Sleazing" values through callbacks that you don't control: sometimes you must call a library method that calls back into your package.  At this point, you need some context that you were unable to pass to yourself, due to deficiencies in the library.  In this rare situation, thread locals can be a lifesaver.
 
In all of these cases, thread locals are the right thing to use.  Can you cause unintended object retention with thread locals?  Sure you can.   But you can do this with arrays too. That doesn't mean that thread locals (or arrays) are bad things.  Merely that you have to use them with some care.  The use of thread pools demands extreme care.  Sloppy use of thread pools in combination with sloppy use of thread locals can cause unintended object retention, as has been noted in many places.  But placing the blame on thread locals is unwarranted.  Virtually all threading systems of which I'm aware provide support for thread local variables.  There's a reason for this: they are a fundamental part of the thread abstraction.
 
           Uappologetically yours,
 
           Josh
 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Unmesh joshi
In reply to this post by Unmesh joshi
Hi,
>>People are using ThreadLocal for things that are not thread-local, in the
>>sense of how ThreadLocal was designed. Hence the problems. Changing
>>ThreadLocal might help alleviate some of the problems, but to me that's
>.somewhat missing the real problem. The applications that reuse threads in
>>different contexts should be the ones ensuring the threads are correctly
>>"configured", with respect to ThreadLocal, when they switch "contexts". For
>>the future we should look at how a ContextLocal variable might be defined.
 >>Just my 2c.
>>
>>Cheers,
>>David Holmes
I was reading a blog by Robert Martin at http://blog.objectmentor.com/articles/2007/09/04/thread-local-a-convenient-abomination. Here he states Jim Coplien saying “An object is an abstraction of function. A thread is an abstraction of schedule.“An object is an abstraction of function. A thread is an abstraction of schedule." and how Unit of Work related variables are often wrongly assigned to ThreadLocal. In coming J2EE concurrency utilities, is there any work going on ContextLocal or UnitOfWorkLocal utilities?
 
Thanks,
Unmesh


Search from any Web page with powerful protection. Get the FREE Windows Live Toolbar Today! Try it now!
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Endre Stølsvik-6
In reply to this post by Joshua Bloch-2
Hi.

I agree wholeheartedly that ThreadLocals are great stuff for many
scenarios. For me, they make lots of sense for carrying some context
forward through method calls whose signatures you cannot or will not
change. And they're fast. And bla bla..

Great..

> In all of these cases, thread locals are the right thing to use.  Can
> you cause unintended object retention with thread locals?  Sure you
> can.   But you can do this with arrays too. That doesn't mean that
> thread locals (or arrays) are bad things.  Merely that you have to use
> them with some care.  The use of thread /pools/ demands extreme care.  
> Sloppy use of thread pools in combination with sloppy use of thread
> locals can cause unintended object retention, as has been noted in many
> places.

Did you read the links in my post?

The point is so: Tomcat is a widely used Servlet Container. ThreadLocals
works perfect for lots of stuff, and everyone is happy.
    However, when a "web application reload" happens, the CURRENT
implementation of ThreadLocal will, given merely one non-nulled
ThreadLocal, and given that Tomcat don't kill _all_ its "worker Threads"
(the ones that have done service calls into the web app) upon any webapp
reload, retain a strong chain to the ThreadLocal's values, hence to
those object's classloader (which is the "now ditched" old webapp
classloader), and hence all the loaded classes. (And I guess further:
hence all those classes' ThreadLocals, which will ensure even better
that their values aren't GCable, since the "cleaning efforts" of the
ThreadLocal implementation will be even more hampered).

One can argue that the application should never let a Thread get out of
the webapp scope with any webapp scoped ThreadLocal value still
non-null. However, the specific user cannot control all usages of
ThreadLocals: it might be in some third party code, or some Exception
happens in some place where one didn't think of ThreadLocal cleanup (one
doesn't tend to handle ThreadLocals with the same care as closing e.g. a
SQL Connection, and even that isn't always done), or again, it happens
in some third party code, where the ThreadLocal simply isn't available
for cleanupping.

Even "java itself", as noted in a comment for bug 6254531, has lots of
such usage that will lead to leak if loaded by a user classloader.

The key point here, is that the old implementation, a map keyed on
Thread, didn't have this problem. The problem was introduced with the
reimplementation for performance improvement that the 1.3 version came
up with, since now the Thread object itself holds a strong reference to
the value, and ditching all references to all objects, and all classes,
and the classloader, WILL NOT any longer be enough to make sure GC can
happen, since one also will have to let all Threads die, taking the
ThreadLocal value references with them..

This last little point is the sole problem the OP referred to - and I
cannot understand that this isn't an unintended consequence of the
performance improvement reimplementation - it definitely is a regression
compared to how the initial implementation worked, that much I hope
anyone will agree to.

Thomas Hawtin ("Tackline" - see links) has apparently come up with some
solution that will ensure that merely a ThreadLocal reference won't make
the referenced value non GCable, which doesn't degrade performance (much).

Kind regards,
Endre.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Endre Stølsvik-6
>
> Thomas Hawtin ("Tackline" - see links) has apparently come up with some
> solution that will ensure that merely a ThreadLocal reference won't make
> the referenced value non GCable, which doesn't degrade performance (much).

I realize this came out wrong..! Of course, it is plenty enough that
"merely a ThreadLocal" references a value - a ThreadLocal shall not work
as a WeakReference or something like that.

The problem is that since the Thread holds a hard reference to the
ThreadLocal value, an entire graph of objects, consisting of the value,
its classloader, and all that classloader's loaded classes (with their
static ThreadLocals again) will be retained, even though no object,
class or classloader in this graph is still in active or actual use (the
entire graph is really "loose", and should be GCable, wasn't it for this
"not really" reference).

Regards,
Endre.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Unmesh joshi
In reply to this post by Endre Stølsvik-6
Thanks Endre for useful links.
So I suppose if I use threadlocal which are not referring to any of the classes in my web module and not using hot deployment feature of app server, I am safe.
I was planning to use threadlocal for saving some user specific context before a http request is handled by my server side classes and clean it up before sending the response. This way, it wont be needed to pass user context (userid and other useful information) to all the methods as parameter.
The example code might be like
RequestContextHolder {
 private static ThreadLocal threadLocal = new ThreadLocal();
 public static Map get() {
        return (Map)threadLocal.get();
 }
 
 public static void set(Map context) {
          threadLocal.set(context);
 }
 
 public static void clearContext() {
       threadLocal.set(null);
 }

}
 
 
class FrontController {
 
 
    public void handleReqeuest(HttpRequst request.....) {
 
               Map requestContext = buildRequestContext(request);
               RequestContextHolder.set(requestContext);
                .....
               Response response = handleRequest(request);
               processResponse(response);
 
               RequestContextHolder.clearContext(); 
 
    }
   
}
 
 
I can think of this as a very convinient when we need to access request context at many placed. This might be a bad practice to use RequestContext at various places rather than passing explicit parameters, but I think in certain scenarios, this might be very handy.
 
Is this a general practice to keep some kind of "execution context" in ThreadLocal?
 
Thanks,
Unmesh
 
P.S. I am not sending this email to whole of concurrency-interest

> Date: Mon, 8 Oct 2007 22:00:18 +0200
> From: [hidden email]
> Subject: Re: [concurrency-interest] Threadlocals and memory leaks in J2EE
> To: [hidden email]
> CC: [hidden email]
>
> Unmesh joshi wrote:
> >
> > Hi,
> >
> > Threadlocals are used in J2EE application servers to keep track of
> > transaction context and security context. I was thinking of using it to
> > pass execution context (which involves some user login and other context
> > information) around in web application which involves servlets and other
> > server side classes. (As discussed at
> > http://www.theserverside.com/news/thread.tss?thread_id=41473).
> > I remember reading somewhere that Threadlocals can cause memory leaks if
> > Threads are getting reused through thread pools. (Which is the case in
> > J2EE application servers).
> > What way can Threadlocal cause memory leak? How Threadlocals behave with
> > Classloaderes in J2EE? In what cases thread local usage is not recommended?
>
> Here's your fix of your information needs!
>
> Vote for this! NOW!
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6254531
>
> Technical low-down on the problem, and a fix:
> http://www.jroller.com/tackline/entry/fixing_threadlocal
>
> .. a quite involved "drop in ThreadLocal replacement" workaround:
> http://www.jroller.com/tackline/entry/working_around_the_threadlocal_leak
> The problem here is that since ThreadLocals might be used in third
> party libraries, you quite possibly end up not being able to replace
> their usages..
>
> (Those links all actually link to each other.. And if you follow links
> further, you'll get even more info..)
>
> In what use cases: when you reuse thread(pools) and at the same time
> change class loaders to implement "reload" functionality. With that
> usage pattern, you will often have the old, reused threads hang onto
> hard references to all the old application instance's ThreadLocal
> values, and thereby also that instance's classes, not permitting these
> to be garbage collected.
>
> So - it basically only happens for "containers" of different sorts, for
> example (and in particular!) Tomcat.
> (The Tomcat guys could easily have fixed it on their side, by either
> hacking into the innards of Thread (by introspection) and "wash" their
> ThreadLocal references, or make a brand new thread pool when any webapp
> is reloaded, letting the old threads die. However, Tomcat seems
> dictatorially lead by this nice chap from JBoss that instantly WONTFIXes
> bugs he personally isn't affected by, without considering the
> implications for others.)
>
> Kind regards,
> Endre.



Check out some new online services at Windows Live Ideas—so new they haven’t even been officially released yet. Try it!
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Gregg Wonderly-2
In reply to this post by Larry Riedel
Larry Riedel wrote:
> I hope I would not be anathema for saying it... my tendency
> would be not to recommend using java.lang.ThreadLocal unless
> there is no apparent (relatively clean) alternative (I still
> think it would have been nice if Thread IDs could not be
> reused).  I like the concept of thread-local variables,
> if they were more a native part of the language and JVM.
> Even so, I wonder how well that concept meshes with thread
> pools where there will be, for example, different threads
> representing the same "user" at different times.

I wonder if a context class loader, exposing a per-thread instance of
ThreadLocal would not be a better solution?

One of the issues with context class loaders, is that the current uses and
mechanics don't provide a chaining mechanism.  So, typically you find

final ClassLoader ld = Thread.currentThread().getContextClassLoader();
try {
        Thread.currentThread().setContextClassLoader( neededLoader );
        ... some code...
} finally {
        Thread.currentThread().setContextClassLoader( ld );
}

when it would be great to have a closure like notation that allowed a context
class loader to be "stacked" on top of a context class loading chain. For mobile
code in clients, "neededLoader" is often just getClass().getClassLoader().  This
is something which I believe should be a more formalized detail.  Especially
since you have to set a context class loader on the AWT event thread, everywhere
(I have a version of SwingWorker that does this for me).

The container/server could provide a context class loader for each thread, that
provided the resolution of ThreadLocal.  Any other additional context would be
stacked on top of that.

There are quite a few things about how the class loading subsystem works, which
could use some attention to make containers (including AWT in a mobile code
environment) have more infrastructure to rely on.

Gregg Wonderly
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Gregg Wonderly-2
In reply to this post by Larry Riedel
Larry Riedel wrote:
> It is not apparent to
> me there are many situations for ordinary application
> programmers where using ThreadLocal would be a better idea
> than just using some sort of application level mapping.

I think containers are using this as a shortcut way of not having to pass a
context object around through all method signatures.  They could of instead,
designed their API so that the user "thread" was manifested inside of a
constructed object which could then expose new context information in fields or
method signatures.

Java servlets have the request and response context enumerated in the API and
this, for me, provides exposure in a way that clearly shows what context you are
  executing in.

In many cases, I think Runnable gets used to often and the end result is that
because an interface is the referred-to type, there is no room for expansion
that subclassing would allow.

Gregg Wonderly
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Larry Riedel
In reply to this post by David Holmes-3

> > My hope was that performance improvement was a major
> > motivation behind the introduction of ThreadLocal;
>
> Performance improvement over what?  An application specific
> version of ThreadLocal?  Or something else?

Improvement over using a Java hash table object which uses
the Thread object as a key... I would hesitate to call that
"thread local" though... rather than maybe just "per thread".


> how you would like to do TLS "properly" with language level
> integration, not just an API to a look-up table.

Virtual address, CPU cache, TLB... to me those are look-up
tables; for me it is a question of providing performance
improvement by leveraging faster lower level mechanisms by
taking advantage of simplifying assumptions (such as that no
locking is needed).

I have not thought much about how I would recommend implementing
it with language and JVM level support; off the top of my head,
I guess a relatively simple approach would be to have the
programmer specify a modifier like "threadlocal" for a variable,
which is similar to "volatile", and in that case the symbol
table entry for a ThreadLocal field in an object instance would
store a reference to a separate per-Thread structure, associated
with that class and instance, which has symbol table entries
for the real references, and the JVM would seamlessly take care
of the creation/destruction and the extra indirection; and of
course that indirection would at some level result in using some
sort of look-up table (eg in the MMU).


Larry

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Threadlocals and memory leaks in J2EE

Gregg Wonderly-2
In reply to this post by Unmesh joshi
Unmesh joshi wrote:
> In coming J2EE concurrency utilities, is there any work
> going on ContextLocal or UnitOfWorkLocal utilities?/

I'd really like to see this "ContextLocal" stuff be supported through a context
class loader mechanism so that the right context could become part of some other
things related to mobile code and/or "plugged-in" code that containers typically
accomidate.  If there was a stackable context classloader mechanism, than the
container creating the execution context could put this context local stuff at
the base of that stack, and the application could then modify and extend the
classloading context as needed to include the use of code from multiple sources.

The Jini PreferredClassLoader and RMIClassLoaderSPI impl, ProferredClassProvider
(and the ClassLoading class) make it easy for a code provider to designate the
"platform" that they are relying on.

Unfortunately, the class loader mechanisms and threading, together create such a
nightmarish view of class loading that it's doubly difficult to get it right.

Gregg Wonderly
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
123
Loading...