## Why is this an issue?

`ThreadLocal` variables are supposed to be garbage collected once the holding thread is no longer alive. Memory leaks can occur when holding threads are re-used which is the case on application servers using pool of threads.

To avoid such problems, it is recommended to always clean up `ThreadLocal` variables using the `remove()` method to remove the current thread’s value for the `ThreadLocal` variable.

In addition, calling `set(null)` to remove the value might keep the reference to `this` pointer in the map, which can cause memory leak in some scenarios. Using `remove` is safer to avoid this issue.

### Noncompliant code example

    public class ThreadLocalUserSession implements UserSession {

      private static final ThreadLocal<UserSession> DELEGATE = new ThreadLocal<>();

      public UserSession get() {
        UserSession session = DELEGATE.get();
        if (session != null) {
          return session;
        }
        throw new UnauthorizedException("User is not authenticated");
      }

      public void set(UserSession session) {
        DELEGATE.set(session);
      }

       public void incorrectCleanup() {
         DELEGATE.set(null); // Noncompliant
       }

      // some other methods without a call to DELEGATE.remove()
    }

### Compliant solution

    public class ThreadLocalUserSession implements UserSession {

      private static final ThreadLocal<UserSession> DELEGATE = new ThreadLocal<>();

      public UserSession get() {
        UserSession session = DELEGATE.get();
        if (session != null) {
          return session;
        }
        throw new UnauthorizedException("User is not authenticated");
      }

      public void set(UserSession session) {
        DELEGATE.set(session);
      }

      public void unload() {
        DELEGATE.remove(); // Compliant
      }

      // ...
    }

### Exceptions

Rule will not detect non-private `ThreadLocal` variables, because `remove()` can be called from another class.

## Resources

- Understanding Memory Leaks in Java