Tomcat에서 배포 해제 메모리 누수를 피할 수있는 방법이 있습니까?
이 질문은 Tomcat 관리자에서 "누수 찾기"버튼을 테스트 한 적이 있고 다음과 같은 결과를 얻은 사람을위한 것입니다.
다음 웹 응용 프로그램이 중지 (다시로드, 배포 취소됨)되었지만 이전 실행의 해당 클래스가 여전히 메모리에로드되어 메모리 누수가 발생합니다 (프로파일 러를 사용하여 확인).
/ leaky-app-name
나는 이것이 빈번한 재배치에서 자주 발생하는 "Perm Gen 공간"오류와 관련이 있다고 가정합니다.
그래서 내가 배포 할 때 jconsole에서 보는 것은로드 된 클래스가 약 2k에서 5k로 이동한다는 것입니다. 그런 다음 배포 해제로 인해 다시 2k로 떨어질 것이라고 생각할 수 있지만 5k로 유지됩니다.
또한 다음 JVM 옵션을 사용해 보았습니다.
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
사용 된 Perm Gen 공간의 양이 아주 약간 감소했지만 예상했던 것과는 달리로드 된 클래스 수가 감소하지 않았습니다.
그렇다면 Tomcat을 구성하거나 배포 해제시 더 잘 언로드되도록 앱을 디자인하는 방법이 있습니까? 아니면 주요 디버깅 세션 후에 서버를 다시 시작해야합니까?
Tomcat 버전 출력 :
서버 버전 : Apache Tomcat / 6.0.29
서버 구축 : 2010 년 7 월 19 일 1458
서버 번호 : 6.0.0.29
OS 이름 : Windows 7
OS 버전 : 6.1
아키텍처 : x86
JVM 버전 : 1.6.0_18-b07
JVM 공급 업체 : Sun Microsystems Inc.
최신 정보:
celias의 답변 덕분에 나는 조금 더 파고 들기로 결정했고 CXF, Spring 및 JAXB 덕분에 내 응용 프로그램에 범인을 결정했다고 생각합니다.
Java 애플리케이션을 프로파일 링하는 방법을 배운 후 Tomcat에서 프로파일 러를 가리키고 힙 덤프와 스냅 샷을 찍어 메모리에서 객체와 클래스가 어떻게 보이는지 확인했습니다. CXF / JAXB (wsdl2java) 생성 클래스에 사용 된 XML 스키마의 일부 열거 형이 배포 해제 후에 남아 있음을 발견했습니다. 내 힙 덤프에 따르면 객체가 맵에 연결된 것처럼 보입니다. 면책 조항 : 저는 아직 프로파일 링에 약간의 녹색이고 객체의 호출 트리를 추적하는 것이 Java에서 어려울 수 있음을 인정합니다.
또한 서비스를 호출하지 않고 배포 한 다음 배포를 취소했다는 점도 언급해야합니다. 객체 자체는 배포시 Spring에서 시작된 리플렉션을 통해로드되는 것처럼 보였습니다. Spring에서 CXF 서비스를 설정하기위한 규칙을 따랐다 고 생각합니다. 그래서 이것이 Spring / CXF, JAXB 또는 리플렉션의 결함인지 100 % 확신하지 못합니다.
참고로 : 문제의 애플리케이션은 Spring / CXF를 사용하는 웹 서비스이고 XML은 다소 복잡한 스키마 ( NIEM 확장 )입니다.
누출이 발생하지 않도록하려면 다음을 수행해야합니다.
- 웹 애플리케이션이 웹 컨테이너 공유 라이브러리에있는 Java 클래스를 사용하지 않는지 확인하십시오. 공유 라이브러리가있는 경우 해당 라이브러리의 개체에 대한 강력한 참조가 없는지 확인하십시오.
- 특히 HashTable, Sets 등과 같은 Java 객체에서 정적 변수를 사용하지 마십시오. 필요한 경우 remove를 호출하여 맵, 목록이있는 객체를 해제해야합니다.
다음의 ThreadLocal과 MemoryLeaks에 좋은 기사가도 - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/
Tomcat 7은이 영역을 개선 할 예정입니다. Apache Tomcat 7의 기능 , No More Leaks! 섹션을 참조하십시오 .
그들은 이제 웹 애플리케이션으로 인한 많은 메모리 누수에 대처할 수 있다고 믿습니다. 불행히도 아직 베타 버전입니다.
그 외에는 같은 경험을했지만 해결책을 찾지 못했다고 말할 수 있습니다. 배포하려면 일반적으로 나중에 Tomcat을 다시 시작해야합니다. 범인이 누구인지 모르겠습니다 : 내 웹 애플리케이션, Tomcat, Hibernate, Tapestry 또는 그 중 일부입니다.
'programing' 카테고리의 다른 글
초기화에 lvalue에서 rvalue로 변환이 수반됩니까? (0) | 2021.01.16 |
---|---|
C ++ 크로스 플랫폼 라이브러리 및 바인딩을위한 최상의 폴더 구조 (0) | 2021.01.16 |
C에서 반환 값 최적화 및 복사 제거 (0) | 2021.01.15 |
WinForms C #의 우아한 로그 창 (0) | 2021.01.15 |
자바 최종 수정 자 (0) | 2021.01.15 |