개발/BE

[Java] Heap Memory 누수 분석기3 : 누수 원인을 분석해보자 - jmap, jhat

kkap999 2024. 3. 1. 16:35
728x90

이전 포스팅에서 이어집니다. : [Java] Heap Memory 누수 분석기2 : 모니터링 환경 구축하기 - VisualVM

 

그래서 VisualVM을 이용하면 로컬 환경에서는 테스트해볼 수 있었는데 사실 그것만으로는 상용 환경에서의 메모리 누수 원인을 확정하기에는 근거가 너무 부족했다.
그래서 jmap 명령어를 이용해서 Heap Dump파일을 생성해보기로 하였다.

Heap Dump

Heap Dump 뜨는 방법으로 jmap 과 jcmd 가 있음

  • jmap : GC를 동반하지 않고, 죽은 객체까지 포함하여 인스턴스의 점유율을 보여준다. jcmd 와 같이 full GC를 발생시키고싶으면 -live 옵션을 붙이면 된다
  • jcmd : Full GC를 발생시킨 후 살아있는 인스턴스의 점유율만 보여줌

처음에는 이 명령어를 써서 수행하려고 했음

jmap -dump:live,format=b,file=heapdump.hprof <PID>

근데 쌓여있는 객체가 너무 많아서 그런지 Full GC 발생시키는 과정에서 리소스 사용량이 엄청 튀고,,, 서버 터질거같아서 생성하지 못하였음

그리고 나중에 안건데, 이런식으로 사용이 완료됐는데 GC에 의해 메모리가 해제되지는 않아서 Leak이 발생하는 상황일 때 저 명령어를 수행하게되면 강제로 그 객체들이 정리된채로 힙 덤프 파일이 생성되게 된다.
그래서 그 덤프 파일로는 메모리 누수 원인 찾기가 힘들 것임

부하와 GC 이슈때문에 아래 옵션으로 덤프파일 생성하였고, 해당 파일을 분석하여 원인을 찾아낼 수 있었다.

jmap -format=b,file=heapdump.hprof <PID>

명령어의 부하와 강제 GC에 대해 주의하면서 덤프 파일을 생성하도록 하자

덤프 분석하는 과정에서 추가적으로 OOM 발생 시 자동으로 Heap Dump 파일을 생성해주는 실행 옵션도 추가해주었음

💡 OOM 발생 시 자동으로 Heap Dump
JVM 실행 옵션으로 아래 옵션을 추가해준다.
-XX:+HeapDumpOnOutOfMemoryError​

jhat

참고링크 : Case Study - Java 메모리 누수(Memory Leak)

# Heap Dump
$ lsof -i:8080    # pid 찾기
$ jps # 이 명령어로도 pid 찾을 수 있음(ApiServerApplication)

Finalizer - finalize()
Cleaner, 
# -dump:live : Full GC 후 dump
# format=b : binary 형식으로 파일 추출
$ jmap -dump:live,format=b,file=heapdump.hprof <PID>

이렇게 덤프를 뜨면 프로젝트의 루트 디렉터리에 .hprof 확장자의 파일이 생성되는데, 이 파일을 분석해야 함

InteliJ를 통해서 바로 열어보는 방법도 있고, jhat 명령어를 통해서도 분석이 가능한 것 같다.

jhat -J-Xmx2048m -port 7001 ./heapdump.hprof

이 주소로 접속해보자 : http://localhost:7001

이런식으로 메모리 사용중인 모든 클래스들이 나온다.

  • Other Queries > Show heap histogram 클릭

처음 5-10개의 오브젝트들이 메모리 유출을 하고 있을 가능성이 높다.

근데 Class [C 는 대체 무슨 클래스인가 ? → Character 배열이라고 한다.

  • Class [C : Character 배열
  • Boolean(Z), Byte(B), double(D), float(F), int(I), long(J), short(S)

근데 힙덤프 파일이 매우 클 경우 jhat 명령어 실행하는 부하도 상당하니 주의하도록 하자.

 

 

하지만 jhat 보기가 조금 불편해서,, 이걸로 찾아내지는 못했고
VisualVM과 MAT라는 툴을 통해 힙 덤프파일을 분석해봄으로서 찾아낼 수 있었다.
다음 포스팅에서는 MAT 사용법과 누수 객체 분석 과정에 대해서 포스팅할 예정이다.

 

오늘의 교훈

  • FullGC하면 누수 객체들이 다 정리된다.
  • FullGC의 부하에 대해서 주의하도록 하자

 

참고 링크