OOM(OutOfMemory) 분석 방법
많은 시스템에서 메모리 문제로 인한 프로세스 다운현상 등의 심각한 장애를 경험한 사례가 있을 것이다.
Java에서는 C와는 달리 가비지컬렉터(Garbage Collector)로 메모리를 관리하기 때문에 개발자의 실수로 인한 메모리릭 발생은 상대적으로 줄어들었다. 하지만 가비지컬렉터가 새로운 객체를 생성할 공간을 더이상 만들지 못하고, Heap 영역 메모리도 더이상 늘어날 수 없는 상황이 발생하게 되면 Java에서는 OutOfMemoryError를 발생시킨다.
물론 네이티브 할당의 문제로 OutOfMemoryError가 발생하는 경우도 있지만 이는 발생확률이 굉장히 낮고, 시스템에서 사용되는 어떠한 객체가 Heap영역을 점유하면서 발생하는 경우가 일반적이다.
지금부터 대규모 시스템에서 OutOfMemoryError 발생 시 빠른 대응을 하기 위해서 모니터링할 수 있는 방법 및 OutOfMemoryError가 발생한 이유를 분석하는 방법에 대해서 알아 보겠다.
(이하 OutOfMemoryError를 OOM으로 대체한다.)
► 모니터링
시스템을 운영하다보면, 특히 오픈한지 얼마 안된 시스템의 경우 문제가 발생하는 경우가 종종 발생한다. 이 때 문제가 어디서 발생했는지를 빠르게 찾아 내야 시스템을 신속하게 정상화 시킬 수 있고, 동일 문제의 재발방지를 위한 조치를 빠르게 할 수 있다.
장애가 발생시 문제가 OOM인지 확인하기 위해서 필자는 OOM 분석을 위한 간단한 Server모니터링 프로그램을 작성하였다.
물론 운영하는 System에 APM Tool을 사용하고 있다면, APM Tool에서 이상상황을 알려주는 경우가 많다. Jennifer의 경우 OOM발생시 DashBoard의 경보목록에서 Process down메시지와 OutOfMemory 메시지를 보여준다.
APM이 없을경우
JVM Option을 통한 Log
- 프로세스 기동시 Option을 추가하여 OOM 발생시 Heapdump를 지정한 경로에 생성하도록 설정할 수 있음
- Heapdump가 생성되는 경로에 새로운 Heapdump가 생성되었는지를 확인 함으로서 OOM이 발생하였는지를 확인함
2.1.2 Jsch를 사용한 OOM 모니터링
수 십개의 서버로 구성되어있을 경우 있으므로 손쉽게 원하는 서버를 모니터링 할 수 있도록 Jsch 라이브러리를 이용한 간단한 프로그램을 작성하였다. Jsch는 Java Program을 통해 sshd서버에 접속하여 원하는 작업을 수행할 수 있도록 하는 라이브러리로, BSD license를 가진 오픈소스다.
작성된 프로그램은 각 서버에 접속하여, 정해진 시간마다 heapdump파일이 발생하였는지 목록을 조회하고, heapdump발생 시 heapdump파일을 다운로드 받을지 여부를 확인하여 sftp로 다운로드하는 간단한 프로그램으로 작성되어있다.
실제 source는 별첨#1에 첨부하였고, Jsch 라이브러리는 http://www.jcraft.com/jsch/에서 다운로드 받을 수 있다.
1) APM Tool 이용(Jennifer) 모니터링
-
- 이상이 있는 Agent의 힙메모리 이상유무 확인
2.2 OOM분석
OOM이 발생하면 먼저 HeapDump파일을 분석하여 어떤 객체에서 메모리를 점유하고 있는지 확인하고, Thread Dump 및 WAS Log 등을 통해 어떤 Stack에서 발생하였는지 확인하여 원인을 파악한다.
2.2.1 Heapdump분석 - IBM HeapAnalyzer
IBM에서는 IBM HeapAnalyzer라는 Tool을 제공하며, 이 Tool을 통해 OOM발생시 생성된 heapdump파일을 쉽게 분석할 수 있다.
HeapAnalyzer를 다운로드받아 아래와 같이 실행한다.
java -Xmx1024m -Xms1024m -jar ha450.jar
heapdump파일이 보통 수백MB이상 크므로
위와 같이 Max Heap Size를 1GB이상 설정하는 것이 적당하며, 다운로드 시간도 상당히 소요되므로 OOM발생시 신속하게 로컬로 다운로드 받도록 해야한다.
(HeapAnalyzer는 Window기반
프로그램이므로 Windows로 접속가능한 상황이 아니라면 보통은 로컬PC로 heapdump파일을 다운로드 받은 후 분석한다.)
Heapdump Array아래와 같이 어떤 객체에서 대부분의 Heap을 점유하고 있는지를 확인할 수 있다.
2.2.2 Log분석
솔루션의 경우 대부분 솔루션 자체 Log를 가지고 있고, 일반적인 경우에는 WAS Log를 통해서 OOM을 분석할 수 있다. WAS의 종류 및 Log level에 따라 조금씩 차이가 있을 수 있으나, 대부분의 WAS Log에는 OutOfMemory Error를 남기므로 어떤 AP를 어떤 Logic수행 중 발생하였는지 확인이 가능하다.
2.2.3 Thread Dump 분석
OOM발생시 Heapdump와 Thread dump를 자동으로 생성할지 여부를 Option을 통하여 설정할 수 있고, 이 때 생성된 Thread dump에는 OOM 발생 당시의 Thread 상태를 확인할 수 있으므로 분석시 용이하게 활용할 수 있다. 이렇게 생성된 Thread dump에는 상단에 Dump Event systhrew Detail"java/lang/OutOfMemory" "Java Heap space" received 라는 Event정보가 출력된다.
Web환경에서 대부분 Multi Thread로 동작하므로 Process에 해당하는 모든 Thread를 확인하여 의심가는 부분을 찾아야 하며, 시간대별로 발생한 Thread dump를 통해 Thread를 추적확인하여 특정 부분에서 계속 걸려있는 Thread가 없는지를 확인해야 한다.
Heapdump에서 확인한 주요 객체가 보이거나, 반복해서 걸리는 객체가 있다면 관련로직을 확인하여 OOM발생 사유를 파악해 볼수 있다.
2.2.4 APM(Jennifer) 활용
OOM을 Jennifer 대시보드의 오른쪽하단에 보면 경보 목록이 있다. 경보정보를 크게 팝업으로 띄워 경보내역을 검색할 수 있고, 시간대별로 발생한 경보내역을 확인할 수 있다. Heapdump발생시간은 heapdump파일에 있으므로 해당시간을 검색하여 어떤 oom발생내역이 있는지 확인할 수 있다. 또한 실시간 모니터링 메뉴에서 그 시간대의 AP를 검색하여 Outofmemory 에러 발생내역의 수행LOG및 profile등 제니퍼에서 제공하는 정보를 상세하게 확인할 수 있다. 또한 제니퍼 경보목록에서는 Connection이 close되지 않았을 경우 경고 메시지를 보여주며, 해당 내용을 확인함으로서 DB Connection full에 따른 OOM발생을 사전 예방할 수 있다.
3. OOM 발생 사례
3.1 반복문을 통해 List에 많은 데이터를 담을 경우
가장 일반적이고 자주 발생하는 Case로서, 특히 List에 VO를 담는 경우에는 어떤 객체에서 문제가 되었는지가 명확하므로 분석이 비교적 쉬운편이다.
- Heapdump 확인 / 객체 확인 / Logic확인
3.2 대용량 파일을 업로드 및 read할 시
- 파일을 읽어서 객체에 담는경우
- 엑셀파일 업로드시 전체 파일을 메모리에 올린 후작업하므로 큰파일을 처리할 시에는 OOM이 발생할 가능성이 큼 -> 업로드 size조정이 필요함
3.3 DB Connection을 close하지 않을 경우
- JSP및 Java에서 사용하는 DB Connection을 close하지 않아 DB Connection Pool이 증가하여 OOM발생 -> finally에서 Connection 객체를 close 해줘야함(close처리완료)
3.4 잘못된 재귀함수의 사용
- sso 솔루션 내부적으로 ioexception발생시 재귀함수를 호출하게 되어있어 에러발생시 반복적 재귀함수호출로 인한 OOM발생 -> 해당업체에서 처리
3.5 BLOB 데이터 Insert시
- BLOB형태로 Insert하기위해 file을 읽어서 ByteArray로 변환하는 과정에서 OOM발생 -> BLOB Data를 Streaming형식으로 Insert 또는 Update하도록 해야함. framework을 사용하지 않고, 직접 JdbcTemplate.query의 mapRow내부에 BufferedReader로 받아서 처리하도록 수정함
Java에서는 C와는 달리 가비지컬렉터(Garbage Collector)로 메모리를 관리하기 때문에 개발자의 실수로 인한 메모리릭 발생은 상대적으로 줄어들었다. 하지만 가비지컬렉터가 새로운 객체를 생성할 공간을 더이상 만들지 못하고, Heap 영역 메모리도 더이상 늘어날 수 없는 상황이 발생하게 되면 Java에서는 OutOfMemoryError를 발생시킨다.
물론 네이티브 할당의 문제로 OutOfMemoryError가 발생하는 경우도 있지만 이는 발생확률이 굉장히 낮고, 시스템에서 사용되는 어떠한 객체가 Heap영역을 점유하면서 발생하는 경우가 일반적이다.
지금부터 대규모 시스템에서 OutOfMemoryError 발생 시 빠른 대응을 하기 위해서 모니터링할 수 있는 방법 및 OutOfMemoryError가 발생한 이유를 분석하는 방법에 대해서 알아 보겠다.
(이하 OutOfMemoryError를 OOM으로 대체한다.)
► 모니터링
시스템을 운영하다보면, 특히 오픈한지 얼마 안된 시스템의 경우 문제가 발생하는 경우가 종종 발생한다. 이 때 문제가 어디서 발생했는지를 빠르게 찾아 내야 시스템을 신속하게 정상화 시킬 수 있고, 동일 문제의 재발방지를 위한 조치를 빠르게 할 수 있다.
장애가 발생시 문제가 OOM인지 확인하기 위해서 필자는 OOM 분석을 위한 간단한 Server모니터링 프로그램을 작성하였다.
물론 운영하는 System에 APM Tool을 사용하고 있다면, APM Tool에서 이상상황을 알려주는 경우가 많다. Jennifer의 경우 OOM발생시 DashBoard의 경보목록에서 Process down메시지와 OutOfMemory 메시지를 보여준다.
APM이 없을경우
JVM Option을 통한 Log
- 프로세스 기동시 Option을 추가하여 OOM 발생시 Heapdump를 지정한 경로에 생성하도록 설정할 수 있음
- Heapdump가 생성되는 경로에 새로운 Heapdump가 생성되었는지를 확인 함으로서 OOM이 발생하였는지를 확인함
2.1.2 Jsch를 사용한 OOM 모니터링
수 십개의 서버로 구성되어있을 경우 있으므로 손쉽게 원하는 서버를 모니터링 할 수 있도록 Jsch 라이브러리를 이용한 간단한 프로그램을 작성하였다. Jsch는 Java Program을 통해 sshd서버에 접속하여 원하는 작업을 수행할 수 있도록 하는 라이브러리로, BSD license를 가진 오픈소스다.
작성된 프로그램은 각 서버에 접속하여, 정해진 시간마다 heapdump파일이 발생하였는지 목록을 조회하고, heapdump발생 시 heapdump파일을 다운로드 받을지 여부를 확인하여 sftp로 다운로드하는 간단한 프로그램으로 작성되어있다.
실제 source는 별첨#1에 첨부하였고, Jsch 라이브러리는 http://www.jcraft.com/jsch/에서 다운로드 받을 수 있다.
1) APM Tool 이용(Jennifer) 모니터링
-
- 이상이 있는 Agent의 힙메모리 이상유무 확인
2.2 OOM분석
OOM이 발생하면 먼저 HeapDump파일을 분석하여 어떤 객체에서 메모리를 점유하고 있는지 확인하고, Thread Dump 및 WAS Log 등을 통해 어떤 Stack에서 발생하였는지 확인하여 원인을 파악한다.
2.2.1 Heapdump분석 - IBM HeapAnalyzer
IBM에서는 IBM HeapAnalyzer라는 Tool을 제공하며, 이 Tool을 통해 OOM발생시 생성된 heapdump파일을 쉽게 분석할 수 있다.
HeapAnalyzer를 다운로드받아 아래와 같이 실행한다.
java -Xmx1024m -Xms1024m -jar ha450.jar
heapdump파일이 보통 수백MB이상 크므로
위와 같이 Max Heap Size를 1GB이상 설정하는 것이 적당하며, 다운로드 시간도 상당히 소요되므로 OOM발생시 신속하게 로컬로 다운로드 받도록 해야한다.
(HeapAnalyzer는 Window기반
프로그램이므로 Windows로 접속가능한 상황이 아니라면 보통은 로컬PC로 heapdump파일을 다운로드 받은 후 분석한다.)
Heapdump Array아래와 같이 어떤 객체에서 대부분의 Heap을 점유하고 있는지를 확인할 수 있다.
2.2.2 Log분석
솔루션의 경우 대부분 솔루션 자체 Log를 가지고 있고, 일반적인 경우에는 WAS Log를 통해서 OOM을 분석할 수 있다. WAS의 종류 및 Log level에 따라 조금씩 차이가 있을 수 있으나, 대부분의 WAS Log에는 OutOfMemory Error를 남기므로 어떤 AP를 어떤 Logic수행 중 발생하였는지 확인이 가능하다.
2.2.3 Thread Dump 분석
OOM발생시 Heapdump와 Thread dump를 자동으로 생성할지 여부를 Option을 통하여 설정할 수 있고, 이 때 생성된 Thread dump에는 OOM 발생 당시의 Thread 상태를 확인할 수 있으므로 분석시 용이하게 활용할 수 있다. 이렇게 생성된 Thread dump에는 상단에 Dump Event systhrew Detail"java/lang/OutOfMemory" "Java Heap space" received 라는 Event정보가 출력된다.
Web환경에서 대부분 Multi Thread로 동작하므로 Process에 해당하는 모든 Thread를 확인하여 의심가는 부분을 찾아야 하며, 시간대별로 발생한 Thread dump를 통해 Thread를 추적확인하여 특정 부분에서 계속 걸려있는 Thread가 없는지를 확인해야 한다.
Heapdump에서 확인한 주요 객체가 보이거나, 반복해서 걸리는 객체가 있다면 관련로직을 확인하여 OOM발생 사유를 파악해 볼수 있다.
2.2.4 APM(Jennifer) 활용
OOM을 Jennifer 대시보드의 오른쪽하단에 보면 경보 목록이 있다. 경보정보를 크게 팝업으로 띄워 경보내역을 검색할 수 있고, 시간대별로 발생한 경보내역을 확인할 수 있다. Heapdump발생시간은 heapdump파일에 있으므로 해당시간을 검색하여 어떤 oom발생내역이 있는지 확인할 수 있다. 또한 실시간 모니터링 메뉴에서 그 시간대의 AP를 검색하여 Outofmemory 에러 발생내역의 수행LOG및 profile등 제니퍼에서 제공하는 정보를 상세하게 확인할 수 있다. 또한 제니퍼 경보목록에서는 Connection이 close되지 않았을 경우 경고 메시지를 보여주며, 해당 내용을 확인함으로서 DB Connection full에 따른 OOM발생을 사전 예방할 수 있다.
3. OOM 발생 사례
3.1 반복문을 통해 List에 많은 데이터를 담을 경우
가장 일반적이고 자주 발생하는 Case로서, 특히 List에 VO를 담는 경우에는 어떤 객체에서 문제가 되었는지가 명확하므로 분석이 비교적 쉬운편이다.
- Heapdump 확인 / 객체 확인 / Logic확인
3.2 대용량 파일을 업로드 및 read할 시
- 파일을 읽어서 객체에 담는경우
- 엑셀파일 업로드시 전체 파일을 메모리에 올린 후작업하므로 큰파일을 처리할 시에는 OOM이 발생할 가능성이 큼 -> 업로드 size조정이 필요함
3.3 DB Connection을 close하지 않을 경우
- JSP및 Java에서 사용하는 DB Connection을 close하지 않아 DB Connection Pool이 증가하여 OOM발생 -> finally에서 Connection 객체를 close 해줘야함(close처리완료)
3.4 잘못된 재귀함수의 사용
- sso 솔루션 내부적으로 ioexception발생시 재귀함수를 호출하게 되어있어 에러발생시 반복적 재귀함수호출로 인한 OOM발생 -> 해당업체에서 처리
3.5 BLOB 데이터 Insert시
- BLOB형태로 Insert하기위해 file을 읽어서 ByteArray로 변환하는 과정에서 OOM발생 -> BLOB Data를 Streaming형식으로 Insert 또는 Update하도록 해야함. framework을 사용하지 않고, 직접 JdbcTemplate.query의 mapRow내부에 BufferedReader로 받아서 처리하도록 수정함
댓글
댓글 쓰기