2014-06-23 1 views
1

플러그인로드 메커니즘이있는 webapp를 개발 중입니다. 플러그인은 별도의 jar 파일에 있으며 각 파일마다 별도의 URLClassLoader으로로드됩니다. 내 앱을 여러 번 재배포 할 때 언젠가 OutOfMemoryError이됩니다.내 응용 프로그램을 다시 배포 할 때 OutOfMemoryError

URLClassLoader은로드 된 클래스에 대한 참조가 여전히 존재하므로 가비지 수집 할 수 없기 때문에 읽은 것입니다.

앱을 다시 배포 할 때 어떻게이 참조를 릴리스 할 수 있습니까?

이 앱은 개발중인 Jetty와 프로덕션 환경 인 Tomcat에서 실행됩니다. Tomcat은 또한이 메모리 누수에 대해 알려줍니다.

+2

자신이 굴린 것을 사용하는 대신 OSGi를 사용하여 플러그인/번들을 관리하는 것을 고려해보십시오. 그것을 적용하는 법을 배우기위한 투자이지만, 결국에는 자신을 유지할 필요가없는 입증 된 기술을 사용하는 것으로 끝납니다. – Gimby

답변

-1

톰캣 6 및 메모리 누수를 일으키는 threadlocals에는 알려진 문제점이 있으며 Tomcat 7의 메모리 보호 기능에서 수정해야합니다.

은 다음을 참조하십시오 http://wiki.apache.org/tomcat/MemoryLeakProtection#customThreadLocal

+3

문제는 Tomcat이 아니라 배포 된 응용 프로그램의 전형적인 문제 패턴입니다. 그러나 Tomcat 7은 제대로 작동하지 않는 앱을 ​​해결하기 위해 노력합니다. – Codo

-1

당신은 웹 응용 프로그램을 배포 취소 할 때 참조를 해제하기 위해 ServletContextListener를 사용할 수 있습니다.

여전히 PermGen 오류가 표시되면 수정해야 할 메모리 누수가 있습니다. 경험상 이것은 웹 응용 프로그램이나 사용중인 라이브러리에있을 가능성이 큽니다. Tomcat에서 메모리 누수를 발견했을 수도 있습니다.

메모리 누수를 추적하는 짧은 버전입니다 :

Start Tomcat 
Undeploy and redeploy the problematic application once 
Use a profiler to examine the heap 
Look for an instances of the WebappClassLoader 
Find the one that is strongly held but has an attribute of started = false 
Trace the GC roots for that instance of the WebappClassLoader 
That will point to your memory leak 

가 좀 더 열심히 할 수있는 메모리 누수의 근본 원인을 찾기. http://people.apache.org/~markt/presentations/2010-08-05-Memory-Leaks-JavaOne-60mins.pdf

+1

Eclipse 맷을 사용하여 힙을 프로파일 링합니다. Java 기본 -> 클래스 로더 탐색기를 사용하여 모든 WebappClassLoader를 나열했습니다. 내 응용 프로그램에 속하는 2 개의 로더를 찾았지만 '시작됨'속성이 없습니다. 나는 Tomcat 8을 사용하고있다. – stevecross

+1

Ah. Tomcat 8 코드를 정리하기 위해 리팩토링을하는 것은 내 잘못입니다. state 속성 값을 살펴 봐야합니다. 원하는 클래스 로더는 STARTED와 다른 상태가됩니다. –

0

플러그인 로딩-메커니즘의 코드가 위치한 : 메모리 누수의 종류를 추적하는 것과 그들이이 프레젠테이션을 볼 발생할 수 있습니다 방법에 대한보다 완전한 설명은

? TOMCAT_HOME/lib의 jar 파일 또는 WAR 아카이브에 있습니까?

모든 클래스가 WAR 아카이브 내에 있으면 누수는 분명히 톰캣 클래스 로딩 메커니즘의 동작과 관련이 있습니다.

Tomcat은 앱을 배포 할 때마다 WebappClassLoader의 새 인스턴스를 만듭니다. 각 WebappClassLoader 인스턴스는 해당 앱이 중지되거나 재배포 된 후에 가비지 수집 대상이되어야합니다. 일반적인 메모리 누수가 발생하면 WebappClassLoader에 대한 강력한 참조가 아직 존재하기 때문에 WebappClassLoaders를 가비지 수집 할 수 없습니다. 이러한 유출을 수정하려면 강력한 참조를 수동으로 제거해야합니다.

당신은 누출을 찾기 위해이 간단한 단계를 수행 할 수

:

  • 는 힙 덤프 오픈을 만들기

      이 (바람둥이 관리자를 사용하여) 서버를 시작하고 응용 프로그램
    • 배포 해제하여 응용 프로그램을 배포
    • 그것과 이클립스 매트
    • WebappClassLoader에서 GC 루트까지 참조 경로를 찾으십시오. (약한 참조와 부드러운 참조 제외)
    • 이제는 WebappClassLoader가 가비지 수집되지 않도록합니다.

    더 많은 정보를 원한다면 여기에서 matlab의 스크린 샷을 게시하십시오.

  • 관련 문제