서비스 모니터링 중 heap 사용량이 많아 뭔가 이상함을 감지했다.
실제로 cpu 사용량은 20% 이하인데 heap 사용량은 40% 정도였다.
그래서 힙덤프를 뜨고 힙덤프를 분석해 보았다.
1. 사용 중인 서비스의 pid를 찾는다
ps -ef | grep java
혹은
jsp -v
명령어를 이용해 실행 중인 서비스의 pid를 찾는다.
2. heap dump를 뜬다
나는 jmap을 이용해서 heap dump를 떴다.
jmap -dump:format=b,file=파일이름 pidId
3. 덤프를 분석한다.
스레드 덤프를 분석할 때는 fastThread를 사용했는데 힙덤프 분석할 때 사용하려니까 용량 초과 메시지가 떴다.
그래서 사용해 본 eclipse mat
https://eclipse.dev/mat/downloads.php
elipse mat을 다운로드 후 실행을 하니...
Version 1.8.0_361 of the JVM is not suitable for this product. Version: 17 or greater is required. MemoryAnalyzer.exe
이라는 에러가 발생했다.
자바 버전을 17로 바꾸라는 말 같다.
스프링 부트를 사용 중이라 jdk가 로컬에 없어서 oracle 사이트에서 jdk17을 직접 설치하고
환경변수까지 변경했다 ^^...
환경변수까지 변경 후 Eclipse Memory Analyzer 가 잘 열린다.
이제 힙덤프 분석을 돌리자...
절반 이상이 문제가 있다.
디테일을 확인해 보니
언뜻 보아하니
jdbc 라이브러리에서 concurrentHashMap을 사용하고 지우질 않고 있는 것 같다.
관련 글을 찾아보니
https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/news-8-0-22.html
jdbc 8.0.22 버전부터 com.mysql.cj.disableAbandonedConnectionCleanup=true 가 적용되어있다고 한다.
이게 적용되어야 jvm에서 클린업을 하는 것 같다. 현재 프로젝트는 8.0.21이었다.
따라서 pom.xml에서 jdbc 라이브러리를 버전 업하면 해결되는 것!
실제로 힙덤프를 뜨고 분석툴까지 사용해 본 것은 처음이라 매우 재미있었다.
끝..
댓글