Q52: How does ThreadLocal work internally and what causes ThreadLocal Memory Leaks?
ThreadLocal stores thread-confined state. Each Thread instance contains a private ThreadLocalMap where keys are WeakReference<ThreadLocal<?>> and values are strong object references.
- Memory Leak in Thread Pools: Thread pool worker threads are reused indefinitely. If a
ThreadLocalvalue is not explicitly removed viathreadLocal.remove(), the strong value reference persists inside the thread'sThreadLocalMap, leaking memory across executions.
Safe ThreadLocal Cleanup Pattern
public class UserContext {
private static final ThreadLocal<User> context = new ThreadLocal<>();
public static void set(User user) { context.set(user); }
public static User get() { return context.get(); }
public static void clear() { context.remove(); } // Mandatory cleanup
}
// Usage in web filter
try {
UserContext.set(authenticatedUser);
chain.doFilter(request, response);
} finally {
UserContext.clear(); // Prevents thread pool memory leak
}💡 Clearing ThreadLocal inside finally blocks prevents thread pool worker reference leaks.
Key Takeaways
- ThreadLocal isolates state per thread.
- ALWAYS call
threadLocal.remove()infinallyblocks when using thread pools.
Knowledge Check
Why must threadLocal.remove() be invoked when executing inside web application thread pools?