Dev

OOME(Out Of Memory Error) 발생 및 해결

칼퇴시켜주세요 2022. 11. 30. 17:49
728x90

프로젝트를 배포하고 실제 테스트 도중에 갑자기 서버가 멈추는 서비스 장애가 발생하였다. 

로깅을 처리해 놓지 않아 에러를 발견하는데 어려움이 있었고 서버를 foreground로 실행하여 어떤 에러가 발생하는지 확인해 보았다. 

에러는 다음과 같았다.( OutOfMemoryError: Java heap space 띠용...????) 

순간 뇌정지가 왔지만 마침 학교에서 운영체제를 배우고 있어 수업때 배운 여러가지 내용이 머릿속을 스쳐지나갔다.

(메모리 초과??, Heap??, 동적할당??, Page fault??, JVM?? 등등....)  

 

처음에는 단순히 힙 사이즈가 작아서 그런가?그럼 JVM의 Max_Heap_Size를 늘려주면 되겠네 라고 생각했었다. 이전에 java는 jvm 위에서 컴파일 되고 실행된다는 것을 알고 있었지만 그냥 java -jar <파일> 이렇게 실행하면 알아서 잘 동작하여 크게 신경쓰지 않았다.

 

 인터넷 검색을 해보니 JVM  최대 힙 사이즈는 실제 물리 메모리의 25%를 기본으로 잡는것을 알게 되었다.

(배포된 서버의 EC2 인스턴스가  4GB RAM이니깐.... JVM의 최대 힙 사이즈는 1GB이네... 그럼 2GB로 늘리자!!!)

FROM base

....

ENTRYPOINT ["java",\
"-Dcom.sun.management.jmxremote.port=1234",\
"-Dcom.sun.management.jmxremote.rmi.port=1234",\
"-Dcom.sun.management.jmxremote.ssl=false",\
"-Dcom.sun.management.jmxremote.authenticate=false",\
"-Dcom.sun.management.jmxremote=true",\
"-Djava.rmi.server.hostname=<host_ip>",\
"-Xmx2048m",\
 "-jar",\
  "/deploy/wowtown_backend/wowTown-backen-0.0.1-SNAPSHOT.jar",\
  "--spring.profiles.active=prod"
  ...
  ]

Dockerfile에서 Xmx2048m 즉 2GB로 설정해 주었다. 하지만 OOME는 계속 발생하였고 원인을 파악하기 위해 jconsole을 사용하여 실제 서버의 cpu, memory, network를 모니터링 하였다. 그 결과...

OOME 사례

(아니... 뭔데.... 스프링은 싱글톤이여서 동적적으로 인스턴스 생성하는 곳이 없을텐데....)

확인 해보니 프론트엔드에서 채팅방을 webSocket 연결하는데 각 방마다 새로운 connection을 요청하였고, 이로인해 서버에서 connection pool이 초과하여 발생한 문제였다. 

 

프론트엔드 코드를 수정하였고 그 결과..!!!!

21:30 분 이후 부터 더 이상 메모리 누수가 발생하지 않았고 JVM에서 GC까지 아름답게 하는 것을 확인 할 수 있었다.

이후에는 GC에 대해 조금더 자세히 공부해봐야겠다.

반응형

'Dev' 카테고리의 다른 글

그리드 분할을 이용한 Weighted A* 성능 최적화  (0) 2023.04.01
A Star Algorithm(A*, Weighted A*)  (0) 2023.04.01
IntelliJ 한글 깨짐 원인 & 해결  (0) 2023.03.11
XML vs JSON vs YAML  (0) 2022.02.07
API 설계  (0) 2022.02.07