== 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

[source,java]
----
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

[source,java]
----
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

* https://www.baeldung.com/java-memory-leaks[Understanding Memory Leaks in Java]



ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Call the "remove()" on "XXX".


'''
== Comments And Links
(visible only on this page)

=== on 25 Jul 2019, 18:38:21 Tibor Blenessy wrote:
For reference, issue in spring-cloud \https://github.com/spring-cloud/spring-cloud-sleuth/issues/27

endif::env-github,rspecator-view[]
