Heap Memory
프로그램이 구동되기 위해서는, 먼저 메모리에 올라가야한다.
메모리는 크게 4가지 ( Code, Data, Heap, Stack ) 으로 나뉘어있다.
그중에서 동적으로 할당되고 해제되는 영역인, Heap Memory 관련해서 작성하려한다.
c에서는 malloc(), free() 등으로 할당과 해제를 반복하며,
java에서는 GC ( Garbage Collector ) 를 통해 자동으로 정리해준다.
2021.04.04 - [서버운영/자바 GC ( Garbage Collection )] - GC ( Garbage Collection )
Heap Dump
Heap Memory는 프로세스가 동작할때 최소/최대 메모리를 지정하며, 할당된 메모리 안에서 동적으로 운영된다.
그리고 할당된 메모리가 부족한 경우, OOM ( Out Of memory )가 발생하며 프로그램이 종료된다.
1) 메모리 누수로 인해 정리가 되지않아, 최대 메모리 사용량에 도달했을 때
2) 현재 남아있는 메모리보다 큰 리퀘스트가 들어왔을 때
OOM이 발생하면 그때의 Heap Memory 상태 스냅샷을 확보할수 있으며,
.hprof 확장자의 heap dump 파일로 저장된다.
-XX:-HeapDumpOnOutOfMemoryError : OOM 발생시 Heap dump 생성
-XX:HeapDumpPath : Heap dump 파일의 위치
OOM이 없더라도, 메모리 누수가 의심되거나 현재의 메모리 상태를 확인하고 싶을 때
jmap을 사용하여, 수동으로 Heap memory 상태를 dump 파일로 저장할 수도 있다.
jmap -dump:format=b,file=$PATH/$file.hprof $PID
Heap dump 분석
주로 Eclipse MAT ( Memory Analyzer Tool )을 사용한다.
사용전에 설치폴더 MemoryAnalyzer.ini 설정파일을 열어, 분석툴의 메모리를 정해주어야한다.
기본 1GB로 되어있지만, Heap dump 파일이 그보다 큰 경우 프로그램이 종료되기 때문이다.
이후에 파일을 넣어주면 아래와 같은 화면이 나온다.
문제로 예상되는 17번 쓰레드가, 전체 1.5GB 중에 94.54%를 차지하고 있었다.
웹로직 기반의 쓰레드이며, MAT는 char[]를 로드하려다가 문제가 발생한것으로 예상했다.
오브젝트 리스트를 살펴보면, MAT 예상대로 char 배열이 1.5GB 대부분을 차지중이었다.
해당 Thread dump 를 분석해보았다.
[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)' at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:48) at java.util.Arrays.copyOf([CI)[C (Arrays.java:3332) at java.lang.AbstractStringBuilder.ensureCapacityInternal(I)V (AbstractStringBuilder.java:124) at java.lang.AbstractStringBuilder.append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder; (AbstractStringBuilder.java:448) at java.lang.StringBuffer.append(Ljava/lang/String;)Ljava/lang/StringBuffer; (StringBuffer.java:270) at com.cspi.cornerstone.container.TemplateParser.transferObjectTag(Ljava/lang/StringBuffer;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/StringBuffer; (TemplateParser.java:368) at com.cspi.cornerstone.j2ee.http.HttpResponse.out(Lcom/cspi/cornerstone/cmps/Composer;)V (HttpResponse.java:130) at jsp_servlet._contents._voc._global_voc._process._detailview.__voc_detailview.run(Lcom/cspi/cornerstone/j2ee/http/HttpRequest;Lcom/cspi/cornerstone/j2ee/http/HttpResponse;)V (__voc_detailview.java:2481) at jsp_servlet._contents._voc._global_voc._process._detailview.__voc_detailview._jspService(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V (__voc_detailview.java:2727) . . . . |
대략 분석해보면
1) OOM이 발생했고
2) Array, String Builder 즉 위의 Char[] =1.5GB 짜리를 String 으로 변환하려다 발생한 OOM?
혹은 추가로 Char 배열이 들어오려다, 메모리가 부족해서 OOM이 발생한것으로 보인다
3) voc 관련한 소스코드쪽에서 유발된 것 같다
실제 분석결과, VOC 본문 ( content ) 작성 시
사용자가 프로그램 예약어를 사용해서 무한루프가 돌면서 내용 생성되는 문제가 있었다.
물론 Dump 분석으로는 정확한 유발지 및 원인을 찾기는 어렵지만,
이처럼 대략적인 방향을 잡을수있다.
'서버운영 > 자바 프로세스 관리' 카테고리의 다른 글
Thread dump (0) | 2021.07.15 |
---|