LeakPatterns: ThreadLocal
Another common source of leaks we found was related to the use of ThreadLocal. A ThreadLocal is a way to attach some data to a Thread, so you can get at it later. They are really useful for a couple of cases.
First, you can cache some value (presumably expensive to compute) and reuse it later. Since the value is associated with the Thread, it is thread-safe (baring any issues with the attached objects themselves). This makes the ThreadLocal an important tool in performance optimizations.
Another good use of ThreadLocal is to hold some context-related information. For example, maybe you need some data that is on the HTTP Request (like URLs, attributes, query parameters) in order to make an authorization decision for access to certain data. Normally, this would mean that all that data (or the Request itself) would need to appear on the authorizer API - and on any API that called that one - and on any API calling those APIs, etc. Or, you could toss the Request data into a ThreadLocal and retrieve it in the authorizer. It becomes context for the call to the authorizer. This is another really useful technique for loosely tying subsystems together.
But in a server environment (like WebLogic), the Threads are usually pooled and reused for request after request. The ThreadLocal is associated with a Thread, and the Thread is associated with a Request - so that is good. Except that the Thread is only temporarily associated with the Request.
So, if ThreadLocal objects are not managed correctly (such that their life-cycle matches that of the Request), you can get all sorts of evil things happening. First, if you were using ThreadLocal for performance, it just might not work since one user session might be handled by many different Threads. Worse, you might leak data from one user to another (when a user’s Request reuses a Thread containing another user’s data).
And in the cases I saw, if that ThreadLocal holds objects that otherwise should be garbage collected, you will get a leak.
The solution is to ensure that your ThreadLocal usages are properly managed. The ThreadLocal should have the same life cycle as the Request, and you should use ThreadLocal.remove() – preferably in a proper finally block - to clean up at the end of your Request.
Technorati Tags: leak, memory, portal, ThreadLocal, WebLogic
1 comment