자바

메모리 누수 해결기 (Minecraft Java Memory leak)

효재감자 2023. 6. 24. 22:49

서버 환경 : i7-8700, 32GB, 램 할당 20GB, Minecraft PaperSpigot 1.12.2, Java 8

서버 동시 접속자 수가 130명 즈음을 넘어가면서, 오후 8시 이후 메모리 사용량이 한계에 도달하기 시작했습니다.

VisualVM 프로그램 이용

 

이후 급격하게 GC(Garbage Collector) 가 일어나면서 전체 유저가 튕기게 되었고, 이후 ClearLag(Plugin)에 의해 10~20분 주기로 몇 초간 렉이 발생하면서 임의로 lagg gc 명령어(ClearLag Plugin에서 강제적으로 GC를 실행하는 명령)를 실행하여 메모리를 낮추어 유지하게 되었고, 이 과정이 일어날 때마다 유저분들은 불편을 겪어야 했습니다. 

ClearLag config.yml, 10분마다 19500을 넘어가면 lagg gc가 실행되게 설정
처음이자 마지막으로 튕김 현상이 있었을 때 로그

/spark tps

며칠 전 TPS 저하 현상이 있어 개선을 했기 때문에 TPS 는 정상이었고, 메모리 쪽에서 무언가 문제가 있다고 생각이 들었습니다.

이에 따라 저는 메모리 사용 현황을 분석해 보기로 했습니다.

일단 /spark heapsummary를 살펴보았습니다. (spark 플러그인 필요)

 

가장 눈에 띄는 건 HashMap 관련이고, 위에 로그에서 본 Criterion도 보입니다. Advancement 도 보입니다.

 

다음은 이클립스의 mat 프로그램(Memory Analyzer)을 이용한 분석입니다.

자세한 사용방법은 https://shonm.tistory.com/646 를 참고하였습니다.

 

먼저 /spark heapdump를 이용해 heap dump를 만들어 주었습니다. (이 과정에서 서버 멈춤이 발생할 수 있으며 plugins/spark 폴더에 저장됩니다)

 

Overview 화면입니다. 먼저 Leak Suspects를 눌러 들어가 줍시다.


1번째 문제부터 살펴보자면 로그, heap summary에서 발견한 주요 문제들이 여기서 보이게 됩니다.

 

 

2번째 문제도 동일합니다. 

 

 

이제 다시 OverView로 돌아가 왼쪽 하단에 Dominator Tree를 클릭해 보겠습니다. 

위에서 본 AppClassLoader가 18.86%, 스크립트 관련이 약 5%를 차지하고 있는 걸 볼 수 있습니다. 

 

 

여기서부터는 해외 포럼의 도움을 받았습니다.

 

https://papermc.io/forums/t/help-needed-with-memory-leak/437

이분도 heap dump를 생성해 분석해 본 결과 저와 같은 결과를 얻게 되었다고 합니다.

 

네...  advancements를 비활성화 하여야 한답니다.  

 

비슷한 게시물입니다.

https://github.com/PaperMC/Paper/issues/3050

 

이렇게 설정한 후 재부팅을 하고 다시 /spark heapsummary 명령어를 이용하여 상태를 살펴보았습니다. (오전 6시 재부팅 후 오후 12시 동접 70명쯤 되었을 때) 

결과는 아주 만족스러웠습니다.

 

17시간동안 912MB나 쌓인 Criterion 관련은,

 

6시간동안 겨우 1개만 있는것을 볼 수 있습니다.

 

HashMap 또한

17시간동안 88,745,405개 -> 6시간동안 2,094,402 개, 10시간동안 2,159,532 개로 엄청나게 개선된 걸 볼 수 있었습니다.

 

개선 전, Uptime 8 hrs 18 min, 메모리 6GB ~ 14GB 사용


개선 후, Uptime 9 hrs 48 min, 메모리 3GB ~ 12GB 사용
VisualVM에서도 이전보다 메모리 사용량이 줄어든 것을 확인할 수 있었습니다.