Tomcat의 ThreadLocal 누수에 대해이 article을 읽었습니다. 첫 번째 예는 다음 코드를 포함합니다.사용자 정의 ThreadLocal 클래스의 ThreadLocal 누설에 대한 설명
public class MyCounter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class MyThreadLocal extends ThreadLocal<MyCounter> {
}
public class LeakingServlet extends HttpServlet {
private static MyThreadLocal myThreadLocal = new MyThreadLocal();
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
MyCounter counter = myThreadLocal.get();
if (counter == null) {
counter = new MyCounter();
myThreadLocal.set(counter);
}
response.getWriter().println(
"The current thread served this servlet " + counter.getCount()
+ " times");
counter.increment();
}
}
모든 클래스가 webapp에 있다고합니다. 그런 다음 내가 이해하지 못하는 클래스 로더 (ThreadLocal를하지 않음) 누출에 대한 다음 설명 설명 :
을 LeakingServlet 적어도 한 번 호출되고 그것을 제공하는 스레드가 중지되지 않는 경우를 우리는 만들어 클래스 로더 누출!
누수는 ThreadLocal 인스턴스에 대한 사용자 지정 클래스와 스레드에 바인딩 된 값에 대한 사용자 지정 클래스가 있기 때문에 발생합니다. 실제로 중요한 점은 두 클래스 모두 웹 클래스 클래스로 에 의해로드되었다는 것입니다.
ThreadLocal 누출에 대한 설명은 끔찍합니다. 요청을 처리 한 스레드가 중지되지 않은 경우 어떻게 ThreadLocal 유출이 발생합니까 (실제로 기사에 클래스 로더 유출이 표시됩니까?). 스레드가 Tomcat 스레드 풀의 일부이고 MyThreadLocal.remove()
이 닫히지 않았기 때문에 스레드가 풀로 반환 된 이후 MyCounter/MyThreadLocal의 webapp 클래스 로더를 가비지 수집 할 수 없습니까? 전화 MyThreadLocal.remove()
이 문제를 해결할 수 있습니까? 나는 이해하지 못한다.
"MyThreadLocal.remove()를 호출하면 해결할 수 있습니까?" – erickson
언제 부를까요? 현재 스레드에서 ThreadLocal 만 정리합니다. 사용자 정의 클래스 대신 AtomicLong을 사용하는 것이 더 좋으며, AtomicLong은 앱을로드 한 클래스 로더 대신 부트 스트랩 클래스 로더에 의해로드되기 때문에 클래스 로더 누수가 발생하지 않습니다. – CodesInTheDark
또 다른 해결책은 내가 만든 ImprovedThreadLocal을 사용하는 것입니다. github에서 찾으십시오. – CodesInTheDark