자바 OutOfMemoryError 해결 하기 (heap memory)

자바에서 java.lang.OutOfMemoryError는 사용할 수 있는 힙 메모리(heap memory)가 부족할 때 발생합니다. OutOfMemoryError 현상의 원인과 해결 방안에 대해 알아보겠습니다.

heap memory

힙 메모리가 무엇인지부터 알아보겠습니다. 힙 메모리는 흔히 로컬 스택(stack) 메모리와 대비됩니다. 스택 메모리는 함수가 호출되면 생성됐다가 호출이 종료되면 메모리도 함께 사라지는 특징을 가지고 있습니다(static 변수는 제외). 반면 힙 메모리는 메모리 블록이 한번 생성되면 종료 명령을 받기 전까지 유지됩니다.

 

여기서 자바의 중요 개념인 가비지 컬렉터(GC)가 등장하는데요. 가비지 컬렉터는 필요 없는 힙 메모리 할당을 스스로 해제시킵니다. 메모리를 알아서 관리해줍니다. 그러나 할당된 메모리가 참조하는 객체가 없음에도 힙 메모리가 지속적으로 자리를 차지하는 경우도 있습니다. 이를 메모리 누수(memory leak)라고 부릅니다. 쓸데없는 메모리가 사용되고 있는 상태를 일컫습니다.

java.lang.OutOfMemoryError

메모리 누수가 발생했든, 실제로 시스템 용량이 부족하든, java.lang.OutOfMemoryError는 JVM이 새로운 객체를 힙 메모리에 할당할 수 없을 때 발생합니다. 이미 힙 메모리가 가득 차 있고, 가비지 컬렉터가 회수할 힙 메모리를 찾지도 못하는 상황입니다.

 

1. 자바 애플리케이션 재시작

이때 가장 단순한 해결 방법은 메모리를 많이 사용하는 자바 애플리케이션을 종료하고 재시작하는 겁니다. 힙 메모리는 애플리케이션이 종료되면 자동으로 해제됩니다. 이 방법으로는 어떤 원인 때문에 가비지 컬렉터가 힙 메모리를 회수하지 못했는지 등을 분석하지 않더라도 일시적인 메모리 누수 문제를 해결할 가능성이 있습니다. 이런 이유로 주기적으로 프로그램을 재시작하는 게 권장되기도 합니다.

 

2. 자바 힙 메모리 크기 수정

자바 힙 메모리의 크기를 수정해주는 방법도 있습니다. -Xms는 초기에 생성하는 힙 사이즈를, -Xmx는 생성할 수 있는 최대 힙 사이즈를 결정하는 옵션입니다. 예를 들어, 아래와 같이 최대 힙 사이즈를 2048BM(2GB)로 늘려줄 수 있습니다.

java -Xmx2048m

3. 자바 힙 덤프 분석

heapdump를 생성하고, 이를 분석해 원인을 해결하는 방법입니다. heapdump란 자바로 실행된 애플리케이션에서 특정 순간에 JVM이 사용하는 메모리의 총합입니다. 트러블 슈팅을 위해 유용하게 사용됩니다. 자바 힙을 통해 메모리를 많이 차지하는 오브젝트를 찾고, 가비지 컬렉터가 왜 이 메모리를 회수할 수 없는지 등을 분석합니다.

 

힙 덤프를 생성하려면 jhat, JVisualVM, for MAT(Eclipse) 등의 툴을 이용합니다. java.lang.OutOfMemoryError가 발생했을 때 자동으로 힙 덤프를 생성하도록 옵션을 거는 방법도 있습니다. 힙 덤프를 분석하는 방법에 대해선 향후 정리해보도록 하겠습니다.

반응형

댓글

Designed by JB FACTORY