"ThreadLocal" 더 이상 사용하지 않으면 확실히 제거해야 합니다.

 

garbage collectorThreadLocal 변수를 사용하고 있는 스레드가 더 이상 없을 때, 정리 대상으로 판단합니다. 즉 스레드 풀을 사용하는 애플리케이션 서버의 경우 ThreadLocal을 점유하던 스레드가 재사용될 때 메모리 누수가 발생할 수 있습니다.

이러한 문제를 방지하려면 항상 remove() 메서드를 사용하여 ThreadLocal 변수의 현재 스레드 값을 제거하는 것이 좋습니다.

또한 set(null)을 호출해서 값을 제거하면, map에 이 포인터에 대한 참조가 유지되어, 메모리 누수가 발생할 수 있습니다. 여러모로 이 문제를 방지하려면 remove()를 사용하는 것이 더 안전합니다.

규칙을 어긴 코드

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); // 규칙을 어긴 코드
   }

  // 이외 DELEGATE.remove()를 호출하지 않은 다른 메소드들
}

규칙을 준수한 해결책

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(); // 규칙을 준수한 해결책
  }

  // ...
}

같이보면 좋은 자료


If you like SONARKUBE, don’t forget to give me a star. :star2:

원문으로 바로가기

Star This Project