2017-12-20 12 views
0

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()이 문제를 해결할 수 있습니까? 나는 이해하지 못한다.

답변

1

설명이 올바르지 않습니다 : 우리는 ThreadLocal를 예를

그 부분이 잘못에 대한 사용자 정의 클래스를 가지고 있기 때문에

누수가 발생합니다. 스레드 클래스의 ThreadLocalMap은 weakReferences를 키에 사용하므로 threadLocal 인스턴스가 사용자 정의 클래스인지는 중요하지 않습니다. 내 사용자 정의 ThreadLocal 클래스를 사용하여 메모리 누수가 없는지 테스트했습니다.

또한 스레드에 바인딩 된 값의 사용자 정의 클래스입니다.

올바른 내용입니다. 값의 경우 스레드는 약한 참조를 사용하지 않으므로 값이 클래스 로더가 가비지 수집되지 않도록하는 사용자 정의 클래스 인 경우 해당 클래스 로더가로드 한 모든 클래스가 스레드 풀에서 스레드가 제거 될 때까지 메모리에 남아있게합니다.

+0

"MyThreadLocal.remove()를 호출하면 해결할 수 있습니까?" – erickson

+0

언제 부를까요? 현재 스레드에서 ThreadLocal 만 정리합니다. 사용자 정의 클래스 대신 AtomicLong을 사용하는 것이 더 좋으며, AtomicLong은 앱을로드 한 클래스 로더 대신 부트 스트랩 클래스 로더에 의해로드되기 때문에 클래스 로더 누수가 발생하지 않습니다. – CodesInTheDark

+0

또 다른 해결책은 내가 만든 ImprovedThreadLocal을 사용하는 것입니다. github에서 찾으십시오. – CodesInTheDark