rspec/rules/S5164/java/rule.adoc

90 lines
2.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

``++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 threads 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.
== See
* https://www.baeldung.com/java-memory-leaks[Understanding Memory Leaks in Java]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::message.adoc[]
'''
== Comments And Links
(visible only on this page)
include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]