목차

  1. OOM (Out of Memory)
    (1) OOM의 발생 원인
  2. OOM과 Garbage Collector의 관계
  3. Dump를 뜨다
  4. MAT 사용법
  5. 참고 자료

 

0. OOM (Out of Memory)

업무를 보다보면 팀 메신저 방에 이따금씩 OOM에 관련된 내용이 공유된다.
메모리가 부족한 에러이니 덤프를 떠서 메모리 누수의 원인을 분석 후 해결방안을 찾으면 되지만, 제대로 이해하고 있다는 느낌이 들지 않았다.
또한 덤프를 뜨는게 해결 방안의 전부인것 같지는 않았다.
이 기회에 관련 용어 및 해결 방안을 정리해보고자 한다.

 

(1) OOM의 발생 원인

오라클 공식 문서

공식문서의 언급에 따르면 OOM은 Java의 Heap 메모리가 부족하여 더 이상 가용한 메모리가 없을 경우 발생한다.
대표적으로 아래 2가지 사례로 발생한다.

 

  1. 장시간에 걸쳐 서서히 메모리 잠식(leak)으로 인한 OOM
    • ex : Cache(어떤 데이터를 여러 쓰레드가 공유해서 사용하는 경우) leak
  2. 순간적으로 과도한 메모리 할당으로 인해 발생
    • ex : 과도한 데이터 조회 (100만건, 200만건 씩 조회해서 메모리를 들고 있는 경우)
    • ex : 과도한 데이터 조작 (String)

 

(2) 해결 방안

원인에 따라 해결 방안은 다양한데, 아래 몇 가지 예시가 있다.

  1. 제일 쉽고 빠른 해결 방법은 서버 재기동
    • 당장은 해결이 될 수 있으나, 장기적으로는 원인을 파악하지 못해 OOM이 재발될 수 있다.
  1. Heap Memory의 크기 증가
    • GC(Garbage Collector) Time의 증가를 동반하기 때문에 충분한 사전 테스트가 요구된다.
    • GC Time의 증가 이유는 Heap Memory가 증가하다보니 더 많은 메모리를 스캔하고, 이에 따라 GC가 수집을 할지 말지에 대한 체크가 더 빈번하게 발생하기 때문이다.
  1. Heap dump 분석
    • OOM이 발생한 시점에 생성된 Heap Dump 분석을 기반으로 많은 Memory를 사용하거나 Memory Leak을 유발하는 로직을 찾을 수 있다.
  1. 부하 테스트 및 모니터링
    • 대표적으로 관련 툴로 JMeter, Visual VM이 있다.
    • 이 방법은 OOM을 사전에 예방하는 방향성에 더 적합하다.

 

1. OOM과 Garbage Collector의 관계

Garbage Collector(GC)의 YGC / FGC

Java는 Young 영역Old 영역으로 메모리를 분할하는데, 신규로 생성되는 객체는 Young 영역에 보관, 오래 살아있는 객체는 Old 영역에 보관한다.

Young 영역Eden, S0, S1 3개의 영역으로 구분되는데, 뒤에 2개는 Survivor 공간이라고도 불린다.
신규 생성 객체는 Eden 영역에 보관되고, Eden 영역이 100% 차게 되면 사용되지 않는 객체는 제거하고 사용되는 객체는 S0으로 이동한다. 이 과정을 Minor GC라고 한다.

또 다시 Eden 영역이 100%가 되면 Eden 영역S0 영역에서 사용하지 않는 객체는 제거, 남은 객체를 S1으로 이동한다.
이때 여러번 Minor GC가 발생했는데도 S1에 오래 살아남는 객체가 있으면, 이 객체는 Old 영역으로 보내진다.

문제는 Old 영역이 100%가 되면 메이저 GC (= Full GC) 가 발생하게 되는데, 이 때, JVM의 동작을 멈추고 Old 영역의 메모리를 정리하게 된다. 결론적으로 메이저 GC가 발생하게 되면 프로그램의 동작이 멈추기 때문에 큰 이슈가 발생할 수 있다.

 

2. Dump를 뜨다

Dump를 뜨는데에는 다양한 툴과 방법이 있다.
대표적으로 Eclipse의 오픈 소스인 MAT을 많이 활용하는데, 우선 해당 툴을 사용하기 전에 아래 조건이 만족어야 한다.

 

💡 힙이 터지기 전에(= OOM이 발생하기 전에) dump를 자동으로 생성하는 JVM 옵션 적용

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump/directory/your-dump-file.hprof

 

이렇게 하면 힙이 터졌을 때 해당 디렉토리에 덤프 파일(=hprof)이 생성된다.
힙이 터지기 전 뿐만 아니라, 현재 돌아가고 있는 JVM의 dump를 뜨는 방법도 있다.

 

💡 현재 돌아가고 있는 JVM의 dump를 뜨는 jamp 명령어

//pid가 1234인 자바 프로세스의 heapdump 파일을 대상 디렉토리에 생성
jmap -dump:format=b,file=/tmp/heapdump.hprof 1234

 

3. MAT 사용법

티끌모아개발님의 자바 HeapDump 생성하는 방법, MAT 이용해 메모리릭 분석하기 - 클릭!

 

위 블로그 링크에 MAT에 사용 방법이 자세하게 나와있으니, 필요시 참고하도록 하자.

 

 

4. 참고 자료

 

OOM: Out Of Memory & GC 가비지 컬렉터, YGC/FGC

OOM, Out Of Memory 에러는 JAVA GC 가비지 컬렉터가 정상적으로 작동하지 않아 발생하는 에러로 Heap 힙 메모리가 가득 찼을 때, 발생하여 서버에 부하를 주게 된다.위와 같은 상황 발생 시, GC 모니터링

velog.io

 

[CS] OOM의 원인과 아주 간단하게 OOM 발생 시키기

outofmemory가 나는 이유 설정된 메모리 대비 요청되는 메모리가 많기 때문에 나타나는 JVM에서 발생하는 에러 설정의 오류나 사용량 초과로 인해 jdk 5 같은 경우는 jdk hotspot 버그로 인해 oom이 났던

onpups.pe.kr

 

OOME(Out of Memory Error)란? + 대중적인 해결법

OOME는 Out Of Memory Error(Exception) = JVM의 메모리가 부족하여 발생한 에러 OOME(Out of memory error)는 물류메모리 기준으로 Heap Meomory(GC)를 설정하게 된다. GC의 구성은 크게 Y와 Old로 나뉘는데 Y에서 처리된

dd0za-1004.tistory.com

 

'👩🏻‍💻 Programming > Etc' 카테고리의 다른 글

Docker compose 명령어  (0) 2023.01.13
Curl 개념 및 사용법  (0) 2022.02.10
Git blame 사용법  (0) 2022.02.04