🚨개요

사내에서 운영 중인 특정 API(tomcat기반 APP)의 JVM Heap 사용률이 지속적으로 70%-80% 이상 유지되며 성능 저하 가능성이 확인되었습니다. 이에 따라 Heap 증설 및 메모리 누수(Memory Leak) 여부를 포함한 분석을 수행했습니다.

 

🛠️ 이슈 사항

  • 4월 중순:
    • JVM모니터링 시작 후 운영 대시보드에서 JVM Heap 사용률이 80% 이상으로 꾸준히 유지됨을 감지
    • 초기 대응으로 개발자와 논의 후 API JVM Heap 사이즈를 1GB → 2GB로 증설
  • 5월 초:
    • 동일 API에서 다시 Heap 사용률이 80% 이상 점유됨
    • Heap 증가 패턴이 동일 API에서 반복됨에 따라 GC 및 Heap 사용 분석 진행

🔍 원인 분석

1. JVM 내부 지표 분석

  • Memory Pool 별 사용률 확인 결과,
    → PS Old Gen 영역의 메모리 사용량이 계속적으로 우상향 (증가-하기이미지참고)
    → Full GC 이후에도 충분히 회수되지 않는 패턴 확인
  • 이는 객체가 장기적으로 메모리에 머무는 현상을 의미하며, Memory Leak 가능성으로 추정

2. Heap Dump 분석

  • 대상 프로세스에서 heap dump 수행 
    ※ -live 옵션은 현재 GC 후 생존 객체만 덤프하며, 내부적으로 Full GC를 트리거
  •  
  • 명령어 : jmap -dump:live,format=b,file=heap_0513.hprof < tomcat PID>
  • Eclipse Memory Analyzer Tool(MAT)로 분석 결과:
    • Problem 1: MySQL Connector 관련 객체가 해제되지 않고 계속 유지


    • Problem 2: SSL Handshake 객체가 누적되어 소멸되지 않음
      
  • 해당 누수 객체들의 Retained Size를 분석한 결과:
    • 총 약 200MB 수준의 메모리 누수 확인
    • 전체 Heap 대비 소규모이나, FullGC 트리거 이후이기에, 누적 시 OutOfMemoryError 가능성 존재



     

3. 누수 규모 판단 관련 유의사항

  • jmap -dump:live는 GC 후 생존 객체만 덤프하므로,
    → 실제로는 GC에 의해 소멸된 일부 객체가 누락될 수 있음
    → 따라서 실제 누수 규모보다 작게 집계될 가능성 존재
    → 추후 heapdump 진행시에는 live 옵션 제외

✅ 조치 내용

  • 개발팀에 Problem 1,2 관련 메모리 누수 공유 및 수정 요청
    • MySQL Connector 재사용 방식 점검
    • SSL Handshake 객체 재사용 또는 해제 로직 적용
  • 모니터링 항목 추가
    • PS Old Gen 사용률 별도 대시보드화
    • Heap 사용량 및 GC 발생 간격 추이 주기적 분석
  • 향후 대응 계획
    • 주기적 HeapDump 스케줄링을 통한 누수 패턴 조기 탐지
    • GC 로그 기반 메모리 증감 패턴 수집 및 자동 알림 설정

 

+ Recent posts