메모리 누수 해결하기 -(1) DB 커넥션 풀을 조정하자(메모리 사용량 절반으로 절감)

Alex·2025년 2월 14일
0

Plaything

목록 보기
109/118

메모리가 처음에는 100mb선이었다가, 이제 150mb선으로 넘어갔다.
점진적으로 늘어나는 데 문제가 있는 것으로 보인다.

heap dumpfile을 생성하고서
MAT으로 이를 분석해보니

Finalizer라는 클래스가 유력한 leak suspect였다.
이 클래스를 봐도 딱히 별 설명이없어서 incoming referenece를 확인해봤다.

PhantomCleanableRef라는 객체가 대부분이었다.

이건 Cleaner 내부에 있는 클래스인데

Cleaner는 객체들의 참조를 관리하고, 불필요한 객체의 clean을 담당한다고 한다.

PhantomCleanableRef 이렇게 list로 관리를 하는데

저 리스트가 비어있지 않은 경우, 더는 참조되지 않는 객체를 정리한다고 한다.

PhantomCleanableRef는 PhantomCleanable을 상속하는데, 이는 자원 정리에 활용되는 객체로 보인다.

내용을 보니 MySQL에서 생긴 문제로 보인다.

우선, DB에서 트랜잭션이 어떻게 되고 있는지 상황 파악을 해보기로 했다.

SHOW STATUS LIKE '%Threads_connected%';

연결된 트랜잭션의 수가 42개나 됐다...!
이게 무슨 일이지??
하면서 트랜잭션 상태들을 좀더 자세하게 조회해봤다.

SHOW PROCESSLIST;

많은 트랜잭션이 Sleep 상태이면서, 오랜 시간동안 대기중이라는 걸 알게 됐다..
HikariCP의 경우 커넥션 풀의 디폴트 숫자가 10인 것으로 알고 있다. 커넥션 풀의 원리는, 미리 만들어놓은 커넥션을 사용하다가 더는 커넥션 풀이 없다면 대기하다가 시간이 넘으면 타임아웃이 되는 방식이다. 커넥션 풀의 개수는 대략적으로 코어개수의 2배정도가 좋다고 한다.

근데 ec2 프리티어는 코어가 1개이기에 2~3개 정도가 좋아보인다.

그래서, 현재 커넥션 풀의 숫자가 몇개로 돼 있는지 보니

!?

40개로 돼 있었다...그래서 트랜잭션이 저렇게 많이 생성되고 연결된 것이다.
이걸 5개로 줄여주자.

(커넥션 수는 10개가 있어야 데드락을 피할 수 있다고 하는데...흠 이건 사용하면서 조정이 필요해보인다)

spring.datasource.hikari.minimum-idle=3 //사용중이지 않을 때도 유휴 커넥션수는 1개로 지정(트래픽이 적을 때도 3개는 항상 준비 상태 유지)
spring.datasource.hikari.idle-timeout=120000 -2분 (현재 3개 커넥션이 유휴상태면, 1개를 제외하고는 시간이 초과되면 정리)
spring.datasource.hikari.max-lifetime=600000 -10분//커넥션의 최대 수명시간

우선 이렇게 변경하고, 계속 추이를 지켜볼 계획이다.

이렇게 변경됐다.

우선 visualVm을 보면 메모리 사용량이 절반으로 줄어들었다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글