유사한 구성으로 다른 메모리 소비

유사한 구성으로 다른 메모리 소비

거의 동일한 하드웨어 구성(모두 > 24GB RAM)을 갖춘 두 개의 서로 다른 서버(oracle jdk7)에 두 개의 서로 다른 tomcat 7 인스턴스가 있습니다. 두 Tomcat 서버 모두 동일한 구성을 가지며 동일한 웹 애플리케이션이 이러한 서버에 배포됩니다. 카탈리나 옵션은 다음과 같습니다:

-XX:PermSize=128m -XX:MaxPermSize=512M -Xmx2048m -XX:+CMSIncrementalMode -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC

부하 테스트를 실행하는 동안(병렬 실행 요청이 많은 REST API에 스트레스를 줌) 서버 중 하나가 발생합니다 java.lang.OutOfMemoryError: Java heap space(여기서는 스택 추적이 있습니다:http://pastebin.com/wuS1MVCC), 다른 서버는 정상적으로 작동합니다. 왜 이런 일이 일어나는지 전혀 모르겠습니다. 비슷한 문제에 직면한 사람이 있나요?

답변1

따라서 Tomcat JVM 중 하나가 할당된 힙 2048MB를 초과하려고 시도하고 있는 것입니다.

시도해 볼 사항에 대한 체크리스트만큼 구체적인 답변을 찾고 있는 것처럼 들리므로 다음과 같이 하세요.

힙 부족은 각 요청마다 조금씩 누수되는 메모리 누수로 인해 발생하거나 로드 시나리오에서는 JVM이 처리할 수 있는 것보다 더 많은 것을 JVM에 던지기 때문에 발생할 수 있습니다. 그 중 어느 것이 문제인지 확인하고 싶으므로 로드를 생성하는 방법을 살펴보는 것부터 시작하십시오.

문제가 높은 수준의 병렬 요청에서만 발생하고 낮은 수준에서는 발생하지 않는 경우 요청 수와 각 요청을 처리하는 데 필요한 메모리가 너무 크다는 문제가 있는 것입니다. 각 요청이 더 적은 메모리를 사용하도록 하거나 어떻게든 동시성을 제한해야 합니다.

동시성에 관계없이 특정 수의 요청이 처리된 후에 문제가 발생하면 메모리 누수가 발생한 것입니다. 그것을 찾아서 기억을 되찾아야 합니다.

두 시나리오 모두 좋은 힙 메모리 분석기를 사용하면 큰 도움이 될 것입니다. YourKit Java Profiler와 같은 좋은 상용 제품이나 Eclipse Memory Analyser와 같은 무료 제품이 있습니다. 자신에게 맞는 도구를 찾고 이를 사용하여 무엇이 메모리를 차지하고 있는지 확인하는 방법을 알아보세요. 프로그램을 시작하기 위해 반드시 도구를 사용할 필요는 없습니다. 서버에서 부하 테스트를 실행하는 경우 JDK의 jmap 명령줄 도구를 사용하여 파일의 힙 덤프를 캡처할 수 있습니다. 그런 다음 도구를 사용하여 덤프 파일을 분석합니다. 이 도구는 힙에서 어떤 개체가 공간을 차지하고 있는지 보여줍니다.

답변2

있다무엇두 시스템이 다르면 동작이 다르지 않습니다. 너무 적은 결과로 인해 GC에 너무 많은 시간을 소비하면 오류가 발생할 수도 있습니다. 힙 한계에 가깝게 실행하면 GC에 이러한 유형의 문제가 발생합니다.

과도한 GC 시간 및 OutOfMemoryError

가비지 수집에 너무 많은 시간이 소요되면 동시 수집기가 OutOfMemoryError를 발생시킵니다. 총 시간의 98% 이상이 가비지 수집에 소요되고 힙의 2% 미만이 복구되면 OutOfMemoryError가 발생합니다. 이 기능은 힙이 너무 작아서 진행이 거의 또는 전혀 이루어지지 않으면서 애플리케이션이 장기간 실행되는 것을 방지하기 위해 설계되었습니다. 필요한 경우 명령줄에 -XX:-UseGCOverheadLimit 옵션을 추가하여 이 기능을 비활성화할 수 있습니다.

관련 정보