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 |
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 |
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 |
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 |
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 |
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 |
> 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 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 |
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 > 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 |
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 |
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 |
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 |
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 |
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 |
>
> 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 |
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 |
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 |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |