How to clean up ThreadLocals

threadlocal remove
java threadlocal performance
alternative to threadlocal
threadlocal executorservice
static threadlocal
threadlocal get returns null
threadlocal<numberformat
threadlocal in web application

Does any one have an example how to do this? Are they handled by the garbage collector? I'm using Tomcat 6.

[JavaSpecialists 229], The cleanup(Thread) method sets the ThreadLocal map in that thread to null, thus allowing all of the entries to be garbage collected. The only clean way to do this is to call the ThreadLocal.remove () method. There are two reasons you might want to clean up thread locals for threads in a thread pool: to prevent memory (or hypothetically resource) leaks, or. to prevent accidental leakage of information from one request to another via thread locals.

Here is some code to clean all thread local variables from the current thread when you do not have a reference to the actual thread local variable. You can also generalize it to cleanup thread local variables for other threads:

    private void cleanThreadLocals() {
        try {
            // Get a reference to the thread locals table of the current thread
            Thread thread = Thread.currentThread();
            Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
            threadLocalsField.setAccessible(true);
            Object threadLocalTable = threadLocalsField.get(thread);

            // Get a reference to the array holding the thread local variables inside the
            // ThreadLocalMap of the current thread
            Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
            Field tableField = threadLocalMapClass.getDeclaredField("table");
            tableField.setAccessible(true);
            Object table = tableField.get(threadLocalTable);

            // The key to the ThreadLocalMap is a WeakReference object. The referent field of this object
            // is a reference to the actual ThreadLocal variable
            Field referentField = Reference.class.getDeclaredField("referent");
            referentField.setAccessible(true);

            for (int i=0; i < Array.getLength(table); i++) {
                // Each entry in the table array of ThreadLocalMap is an Entry object
                // representing the thread local reference and its value
                Object entry = Array.get(table, i);
                if (entry != null) {
                    // Get a reference to the thread local object and remove it from the table
                    ThreadLocal threadLocal = (ThreadLocal)referentField.get(entry);
                    threadLocal.remove();
                }
            }
        } catch(Exception e) {
            // We will tolerate an exception here and just log it
            throw new IllegalStateException(e);
        }
    }

How to shoot yourself in foot with ThreadLocals, In the very same way your Spring beans can be for example container, session or request scoped. ThreadLocal equips you with the possibility  Once we are done with using the ThreadLocal, we should always call the remove () method before letting the thread return to the pool. The cleanup (Thread) method sets the ThreadLocal map in that thread to null, thus allowing all of the entries to be garbage collected.

There is no way to cleanup ThreadLocal values except from within the thread that put them in there in the first place (or when the thread is garbage collected - not the case with worker threads). This means you should take care to clean up your ThreadLocal's when a servlet request is finished (or before transferring AsyncContext to another thread in Servlet 3), because after that point you may never get a chance to enter that specific worker thread, and hence, will leak memory in situations when your web app is undeployed while the server is not restarted.

A good place to do such cleanup is ServletRequestListener.requestDestroyed().

If you use Spring, all the necessary wiring is already in place, you can simply put stuff in your request scope without worrying about cleaning them up (that happens automatically):

RequestContextHolder.getRequestAttributes().setAttribute("myAttr", myAttr, RequestAttributes.SCOPE_REQUEST);
. . .
RequestContextHolder.getRequestAttributes().getAttribute("myAttr", RequestAttributes.SCOPE_REQUEST);

Java ThreadLocal remove() Method with Examples, How do you clear a local variable in a thread? Thread pools which are smart enough to clean-up ThreadLocals without whinging at you. Thread pools which allocate Threads on a 'per application' basis, and then let them die when the application is stopped.

I would like to contribute my answer to this question even though it's old. I had been plagued by the same problem (gson threadlocal not getting removed from the request thread), and had even gotten comfortable restarting the server anytime it ran out of memory (which sucks big time!!).

In the context of a java web app that is set to dev mode (in that the server is set to bounce every time it senses a change in the code, and possibly also running in debug mode), I quickly learned that threadlocals can be awesome and sometime be a pain. I was using a threadlocal Invocation for every request. Inside the Invocation. I'd sometimes also use gson to generate my response. I would wrap the Invocation inside a 'try' block in the filter, and destroy it inside a 'finally' block.

What I observed (I have not metrics to back this up for now) is that if I made changes to several files and the server was constantly bouncing in between my changes, I'd get impatient and restart the server (tomcat to be precise) from the IDE. Most likely than not, I'd end up with an 'Out of memory' exception.

How I got around this was to include a ServletRequestListener implementation in my app, and my problem vanished. I think what was happening is that in the middle of a request, if the server would bounce several times, my threadlocals were not getting cleared up (gson included) so I'd get this warning about the threadlocals and two or three warning later, the server would crash. With the ServletResponseListener explicitly closing my threadlocals, the gson problem vanished.

I hope this makes sense and gives you an idea of how to overcome threadlocal issues. Always close them around their point of usage. In the ServletRequestListener, test each threadlocal wrapper, and if it still has a valid reference to some object, destroy it at that point.

I should also point out that make it a habit to wrap a threadlocal as a static variable inside a class. That way you can be guaranteed that by destroying it in the ServeltRequestListener, you won't have to worry about other instances of the same class hanging around.

Is it a bad practice to use a ThreadLocal Object for storing web , practice (there's a whole set of problems associated with global variables - search it on the net) b) it may lead to memory leaks, in any j2ee container than manages its threads, if you don't handle it Failing to clean up a ThreadLocal is not generally a memory leak - for example if you're using a ThreadLocal<Integer> the space taken up with the Integer will be negligible compared to the space taken with the rest of the Thread's resources.

Reading again the Javadoc documentation carefully:

'Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist). '

There is no need to clean anything, there is an 'AND' condition for the leak to survive. So even in a web container where thread survive to the application, as long as the webapp class is unloaded ( only beeing reference in a static class loaded in the parent class loader would prevent this and this has nothing to do with ThreadLocal but general issues with shared jars with static data ) then the second leg of the AND condition is not met anymore so the thread local copy is eligible for garbage collection.

Thread local can't be the cause of memory leaks, as far the implementation meets the documentation.

Java ThreadLocal Example, var should be removed before response to the client, thus current thread may be reused by next request. No. ThreadLocals are associate with Threads, not with execution of a Callable/Runnable passed to a threadpool's task queue. Unless explicitly cleared - @PeterLawrey gives an example on how to do so - ThreadLocals and their state persist through multiple task executions.

When and how should I use a ThreadLocal variable?, cleanup() or .close() method – the calling code will be responsible for cleaning all used resources (include threadlocals). Many libraries already  Unfortunately afterView is still called before any layouts are rendered, meaning if you clean up your threadLocal in afterView it will not be available inside a layout. – David Jun 27 '12 at 11:33 add a comment |

ThreadLocal Variables and Thread Pools, getDeclaredField("threadLocals");. threadLocalsField.setAccessible(true);. Object threadLocalTable = threadLocalsField.get(thread);. // Get a reference to the  Thing is: The LazyHandleSupplier also handles the clean-up of the ThreadLocals that itself has set to the Handle by this setter. Seems good. Seems good. It handles the things it created.

A Hacky Way to Clean All Thread Local Variables of Current Thread , ThreadLocal.remove() method removes the current thread's value for this returns the current thread's value of this thread-local System.out.println("value = " +  Slow & Cluttered PC? Clean It Up with the New Avast Cleanup. Download Free Now! Enjoy Longer Battery Life, More Disk Space and Faster PC.

Comments
  • thanks for the reply. The problem is that i can only remove the threadlocal once im done with the request. and i have no easy way to know when im done with the request. the way im doing is i have an interceptor at the start of the request that sets the threadlocal (its a static). so i reset it at the start of each request...
  • If the threadlocal object is a static, leak is more manageable issue; i.e. you only leak (up to) one instance (one thread local value) per thread in the thread pool. Depending on what the thread local values are, this leak could be not worth bothering about.
  • Even if you use static ThreadLocal you can have a class loader leak when you redeploy your webapp if your value refer to some class loaded by the same class loader. It can happen if you use double brace initialization because that would create an anonymous class. I created a fix for that: github.com/codesinthedark/ImprovedThreadLocal
  • This deletes everyone's global variables for the thread, which bit me in Java 6. java.util.concurrent.locks.ReentrantReadWriteLock would occasionally throw an IllegalMonitorStateException because we had deleted its cachedHoldCounter, so it tried to decrement it below 0. This particular issue doesn't happen in Java 8, but who knows how other ThreadLocals react to this, like Spring connections or log4j MDC.
  • Do we need to check threadLocal value is loaded by this webapp's classloader? threadLocal.get().getClass().getClassLoader() == Thread.currentThread().getContextClassLoader()
  • MethodHandle is fast but it is not zero overhead. In some cases its even slower than reflection. It's also not even supported by Graal VM static-image where as reflection is so long as the class and method name can be statically determined (ie constants).... so yeah at the present state of method handle @lyaffe's answer is probably better.
  • MethodHandles used in the first way in "even slower than reflection" web page is definitely slow. However, if you put the MethodHandle in a static final field (the second way in the web page and the way in my answer), then JIT eliminates the overhead. The article says this is useless; however, I have used static final MethodHandles in many places in my code. I find it useful. I guess the usefulness depends on the usecase.
  • Well the bigger issue for me/us is we hope to eventually target Graal VM for our microservices. We don't need the above particular code for these services but Graal VM not supporting MethodHandle does give me pause. Since you work for Oracle (yes I clicked on your profile :) ) maybe you know if they ever plan on supporting them (methodhandles)?
  • Unfortunately, I cannot answer if Graal VM will or will not support MethodHandle. I do not even know who is on the Graal VM team.