이를 Eclipse Memory Analyzer로 분석하는 방법을 포스팅하고자 한다.
1. 아래와 같은 코드를 작성
import java.util.ArrayList; import java.util.List; class HeavyInstance { char[] data = new char[10000000]; } public class OOMTest { public static void main(String[] args) { List<HeavyInstance> dataList = new ArrayList<HeavyInstance>(); while (true) { dataList.add(new HeavyInstance()); } } }무조건 OutOfMemory 에러가 발생할 수밖에 없는 코드다.
2. 위 java application을 jar로 생성
Project > Export > Java > Runnable JAR file
Finish를 누르면 실행 가능한 jar 파일이 생성된다.
3. Jar 파일 실행
위 jar 파일을 실행하면 OOM이 발생하고, 아래와 같은 메시지와 함께 어플리케이션이 종료된다.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at test.HeavyInstance.<init>(OOMTest.java:14) at test.OOMTest.main(OOMTest.java:30)하지만 우리가 원하는 heap dump 파일을 생성하지는 못한다. 바로 아래와 같은 JVM 옵션을 주고 jar파일을 실행해야 heap dump 파일이 생성된다.
c:\> java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:\dumps -jar oom-test.jar위 옵션을 주면, HeapDumPath 옵션에 지정한 경로로 아래와 같이 '.hprof' 확장자를 가진 dump 파일이 생성된다.
Confer.
jar파일을 생성하고 커맨드 라인에서 실행하기 귀찮다면, 아래 run configuration을 설정하여 JVM 옵션을 적용한 채로 이클립스에서 곧바로 실행 할 수 있다.
4. Eclipse Memory Analyzer(이하 mat)로 분석하기
mat는 무료이며, 아래에서 다운 받을 수 있다.
https://eclipse.org/mat/
heap dump 파일(.hprof) 을 이용해 momory leak 등 메모리 성능 이슈를 찾기에 용이한, 공짜치고는 훌륭한 툴인 것 같다.
mat를 실행하고 아래와 같이 방금전 추출한 dump 파일을 open한다
파일을 선택하면 3가지 옵션이 나오는데, 여기서는 Leak Suspects Report를 선택한다.
이는 자동적으로 dump 파일을 parsing하여 어떤 객체가 GC되지 않고 계속 살아있어 OOM의 원인이 되는지 분석해준다.
Finish 를 누르면 아래와 같은 화면이 노출 된다.
노란색 박스 아래쪽에 있는 'Details' 를 클릭하면, 생성된 instance의 갯수, 얼마나 heap 공간을 차지하는지 등, 상세한 정보가 나온다. 이를 통해 OOM의 원인을 분석할 수 있을 뿐만 아니라 잠재된 memory leak 이슈를 발견 할 수 있다.
5. 마치며..
'mat' 라는 툴은 앞에서도 말했지만 공짜치고는 상당히 디테일한 정보들을 제공 한다. 위의 예제에서는 아주 간단한 OOM 발생 어플리케이션의 예 였지만, 좀더 복잡한 자바 어플리케이션은 분석하기가 상당히 까다로울 것이다. 따라서 'mat' 툴에 대한 공부도 계속해서 해야 할것 같다....