|
IBM JVM에서 Memory Leak의 발견과 대처
자바스터디 네트워크 [www.javastudy.co.kr] 조대협 [bcho_N_O_SPAM@j2eestudy.co.kr]
Memory Leak이란, Java Application에서 객체 사용을 위해서 메모리를 할당한후에, 그 메모리를 회수 하지
못하고 잔여 객체들이 메모리 상에 남아 있어서 가용 가능한 메모리양이 줄어들어 결과적으로 Out Of Memory 에러를
발생시키다가 서비스가 불가능한 상태가 되는 현상을 이야기 한다. |

<그림 1. Memory Leak이 발생할때의 GC Graph 상황> 일반적으로 Memory Leak이 발생할 경우 Memory 사용 상황을 모니터링할 수 있는 GC로그를 보면 <그림 1.>과 같은 형태를 띠게 됨으로 GC Graph를 통해서 그 증상을 확인할 수 있다.
Memory Leak의 문제 해결의 절차는 <그림2> 와 같이 이루어 진다. 먼
저 Memory Leak이 있는 증상을 발견하면 Profiling을 통해서 Memory Leak이 발생하는 Point를 발견하고
Application 문제일경우에는 해당 Application을 수정하며, WAS의 문제일경우에는 해당 상황에 대한 자료를
수집하여 Memory Leak을 해결하는 패치를 제작하여 적용하게 된다.

<그림 2. Memory Leak의 해결 절차> 일
반적으로 Leak의 원인을 발견하는 과정은 Jprobe등의 Profiling Tool을 사용해야 하나 IBM JVM의 경우 그
순간의 Memory 사용량을 볼 수 있는 Heap Dump 기능을 제공하기 때문에 이를 이용하면 Memory Leak현상을
발견할 수 있다.

<그림 3.Memory Leak 분석을 위한 Heap Dump의 수집 시점> Heap
Dump를 추출하기 위해서는 먼저 운영후 초기(start하자 마자가 아니라 어느정도 운영이 된후)의 Heap Dump를
수집하고(Heap Dump1), Out Of Memory가 나오기전에 메모리 증가가 커졌을때 Heap Dump를 수집해서
(Heap Dump2) 변화된 내용을 분석하여 Leak이 되는 Object를 판별한다.
IBM에서 Heap Dump의 수집과 분석
1) Heap dump의 수집
IBM에서 Heap Dump를 받기 위해서는 환경 변수에 아래 내용을 추가한다.

그후, heap dump를 받으려는 시점에 kill -3 pid를 해주면 heapdump.xxx라는 이름으로 heap dump 파일이 생성된다.
2) Heap dump의 분석
먼저 Heap Dump를 직접 보기가 어렵기 때문에 분석할 수 있는 도구를 받을 필요가 있는데, http://alphaworks.ibm.com/tech/heaproots에서 분석 도구를 다운받아서 설치하고
% java ?jar xxxx/HR205.jar heapdump파일명
을 입력한다.
프롬푸트에서 os 1-5 를 입력하면 현재 메모리를 가장 많이 차지하고 있는 상위 5개의 Object들을 보여준다.
 ※ os는 각각의 객체 사이즈가 큰것부터 sorting을 하는것이고, ot는 전체 객체 사이즈 (referencing하고 있는)가 큰 순서부터 출력을 한다.
다
음 i명령어를 입력하고 address입력부분에 위에서 메모리를 많이 차지하고 있는 Object의 주소를 입력하면 그
Object에 대한 정보를 보여주고, 그 Object를 Reference하고 있는 Parents Object를 보여준다. 다시
i 명령을 입력해서 상위 Object를 찾아가다보면 실제로 어디서 Leak이 나왔는지를 찾을 수 있다.

다른 방법으로는 prompt에서 d를 입력하면 Memory를 얼마 이상 점유하고 있는 object들의 stack trace를 추출할 수 있다.

위에서 부터 root node이고 표현방식은 다음과 같다.
<Node depth> [이 객체가 referencing하고 이는 총 메모리 크기] 주소 [현재 Object 자체 크기] class명
이 정보를 통해서 어느 부분에서 메모리를 많이 차지하고 있는지를 trace할 수 있다.
위에서 설명한 HeapRoot는 Text기반 툴이기 때문에, Tree형태의 메모리 구조를 탐색하기가 쉽지가 않다.
그래서 HeapRoot의 GUI버전인 HeapAnalyzer라는 툴이 있는데, http://alphaworks.ibm.com/tech/heapanalyzer 에서 다운받아서 설치할 수 있다.
HeapAnalyzer를 이용해서 Memory Leak을 분석해서 Analysis의 Treeview를 보면 다음과 같은 정보를 얻을 수 있다.

먼저 root stack에서 부터 하나하나 child node를 탐색하다보면 객체가 가지고 있는 total memory 사용량이 점차적으로 감소하고 있음을 확인할 수 있다. <그림에서 1) 부분 > 그
림에서 2) 부분에 보면 메모리 할당량이 420M에서 갑자기 319M로 급격히 떨어짐을 볼 수 있는데, 나머지 약 100M의
객체들이 모두 java.util.HashMap$Entry 객체들로 모두 일정하게 33k,27k의 용량을 가진 객체들로 판단할 수
있고, 이런 객체들이 모여서 100M정도의 메모리를 소요하고 있음을 볼 수 있다. <그림에서 3) > 이
HashMap객체들이 어떤 내용을 가지고 있는지 Tree를 열어보면 JMSConnection 객체들을 가지고 있음을 볼수 있고,
결론적으로 이는 JMSConnection 객체 관련 모듈의 Memory Leak현상으로 판단할 수 있다.
|
|