Heap Dump 분석 - Jmap & Eclipse Memory Analyzer(MAT)
Java Application을 개발하고 운영하다 보면 메모리 누수 즉, OutOfMemoryError를 겪는 경우가 있다. 그 중에서도 힙 메모리 공간이 부족해서 생기는 에러인 java.lang.OutOfMemoryError: Java heap space이 발생했을 때 HeapDump 분석을 하는 방법에 대해서 정리한다.
Heap Dump 분석 - Jmap & Eclipse Memory Analyzer(MAT)
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError 예외는 메모리 누수 상황이 발생했을 때 발생하며 그 중에서도 Java heap space 예외는 JVM 내 힙 공간이 부족하여 생기는 예외이다. 힙은 서버를 구동할 때 앞으로 사용할 메모리를 미리 할당하게 되는데 설정한 최대 힙 메모리 용량보다 넘치게 되면 해당 에러가 발생할 수 있다.
해당 에러가 발생한다고 무조건 메모리 누수를 의미하는 것은 아니다. 순간적으로 힙 메모리 사용량이 늘어나서 발생했을수도 있고 구현상의 버그로 인해서 GC(Garbage Collection)가 과도하게 일어나면서 성능이 저하되어 발생할수도 있다.
java.lang.OutOfMemoryError: Java heap space와 관련하여 문제 해결 방법에 JVM 옵션에서 힙 옵션을 늘려줘서 해결하는 방법도 있지만 해당 방법은 정말로 해당 서비스 내에서 필요한 힙의 사이즈를 작게 설정했을 때의 문제 해결 방법이지 근본적인 원인 해결방법은 아니기 떄문에 무작정 크게 늘려줄수는 없다.
(JVM Heap Option에 관해서는 다음 글을 참고)
이러한 경우에 Heap의 높은 사용량을 만든 원인을 알아보기 위해 할 수 있는 방법이 Heap Dump를 이용하여 분석하는 방법이다.
HeapDump
HeapDump는 특정 시섬에서의 Heap 메모리 사용을 파일로 저장한 것이다. HeapDump을 분석하면 메모리를 어디서 많이 사용하는지 확인을 할 수 있다.
HeapDump 파일을 생성하고 분석하는 방법은 여러가지가 있을 수 있지만 그 중에서도 Jmap을 이용하여 HeapDump 파일을 생성하고 생성된 파일을 Eclipse Memory Analyzer(이하 MAT)를 통해 확인하는 방법에 대해서 알아본다.
여기서 Jmap이란 JDK에 포함된 툴로써 현재 실행중인 자바 프로세스의 힙 덤프를 생성을 할 수 있도록 도와준다.
그리고 MAT는 힙덤프 파일을 GUI를 통해 분석할 수 있도록 도와주는 툴이다. (참고로 JDK에서 제공하는 툴인 Jhat을 통해서도 분석이 가능하다)
Jmap을 통한 HeapDump 파일 생성
먼저 HeapDump 파일을 생성하기 위해 Jmap 사용을 위해서는 파일을 얻고자하는 프로세스의 ID인 PID를 알아야한다.
JPS 명령어를 통해서 손쉽게 JVM의 PID를 확인할 수 있다.
jps or jps -v
이렇게 확인한 pid를 아래 명령어에 넣어 HeapDump 파일을 생성해준다.
jmap -dump:format=b,file=heapdump.hprof [PID]
다음과 같이 생성이 된 걸 확인할 수 있다. (서버 내에서 확인을 하고자 한다면 find 명령어를 통해 파일을 확인해준다.)
Heap Dump 파일 분석을 위한 Eclipse Memory Analyzer (MAT) 사용법
먼저 아래 링크를 통해 다운을 받아주자. 자신의 OS 환경에 맞게 다운을 해준다.
https://www.eclipse.org/mat/downloads.php
다운 완료 후 MAT를 실행해주면 다음과 같이 뜰 것이다.
여기서 아래에 있는 Open a Heap Dump 를 눌러 아까 생성했던 hemp dump 파일을 선택해준다. (만약 ec2와 같은 원격 서버에 있다면 생성한 파일을 로컬로 다운을 받아서 실행해준다.)
선택 후 확인을 누르면 다음과 같이 분석을 해준다.
해당 부분에서 아래쪽의 Dominator Tree를 눌러준다.
그러면 다음과 같이 Heap Dump를 뜰 당시에 만들어진 Java 객체들을 한 눈에 확인을 할 수 있다. Percentage 별로 정렬을 해주기 때문에 비정상적으로 높은 퍼센트를 차지하고 있는 객체를 찾아 Heap의 높은 사용량을 만든 원인을 파악할 수 있다.
그리고 해당 항목들을 타고 들어가면 더 정확한 객체를 확인할 수 있다.
추가적으로 이전에 정리한 VisualVM 글에서도 Heap Dump 파일과 관련된 내용 외에 JVM 메모리 분석에 대한 내용도 있으니 참고해보면 좋을 것 같다.