Kim-Baek 개발자 이야기

[카카오 면접] Java Out Of Memory ( OOM ) 본문

개발

[카카오 면접] Java Out Of Memory ( OOM )

김백개발자 2020. 8. 12. 22:58
카카오 면접을 준비하면서, 공부했던 내용을 정리해놓고 다시 기억하기 위한 포스팅

Java의 OOM와 Memory Leak

자바는 Garbage Collection이라는 메모리 관리방식을 채택하고 있어서, 사용자는 메모리에 큰 관심을 두지않고도 어플리케이션을 작성할수 있지만, 떄로는 메모리 누수 (Memory Leak)에 관심을 가져야 할 때가 있다. 

 메모리 누수란 Garbage Collection되어야 할 메모리가 정리되지 못하고 계속 Java의 메모리 공간에 남아있는 현상을 말한다. 이 Memory Leak이 계속 되면 결국 OOM( Out Of Memory - 메모리 부족)현상이 발생해서 어플리케이션이 더이상 동작하지 못하고 JVM이 종료되는 최악의 상황이 된다. 그러므로 상용, 특히 24시간 서비스하는 웹서버등의 경우에는 항상 이 메모리 누수 현상이 발생하지 않는지 관심을 둘 필요가 있다.

 메모리 릭의 양이 아주 작고 메모리는 많은 경우에는 주기적으로 JVM을 재시작 하면서 크게 신경안써도 될 경우도 있지만,  메모리릭이 빠르게 증가하는 경우에는 반드시 해결해줘야 한다.  

OOM왜 발생할까?

크게 보았을 때 OOM가 나는 이유는 단순하다. 메모리를 어플리케이션에서 강참조를 하고 있기 떄문이다. 강 참조란 대부분의 일반적인 변수 참조를 말한다. 예를 들어 static HashMap mapper = new HashMap(); 같은. static같은 정적 메모리로 선언되어있다면 메모리에서 지워지않고 계속 남을 것이다. 의도한 코드가 아닌 경우 릭으로 발전할수 있다. 

어떻게 OOM의 원인, 즉 memory leak을 찾을까?

1) JVM이 OOM exception으로 정지된것을 확인

2) 정지된 JVM의 메모리 영역을 확인했더니 특정영역이 Full 로 가득차있고, GC후 메모리 할당을 받는 것에 실패한것을 확인.

3) 위 글에 정의된것 처럼 영역에 따른 원인을 추정한다. 

4) 코드레벨에서 바로 수정이 가능한 것인지를 확인한다. 많은 경우 싱글톤이나 static을 잘못 사용했을 확률이 높다.

5) 쓰레드 생성이나 JNI에서 OOM이 나는 경우에는 OS의 자원소진일 우려가 있다. 이 경우 외부자원을 조심스럽게 쓰던지, 외부자원량을 늘려야 한다.

6) 프로젝트 규모가 큰경우거나 외부라이브러리를 적극적으로 사용한경우에는 문제의 해결이 쉽지 않다. JVM옵션과 tool의 도움을 받는다.

- jvm 시작시에 -verbose:gc옵션을 추가한다. 가비지 콜렉션 로그를 자세히 볼수 있다.

jvm 시작시에 -XX:+HeapDumpOnOutOfMemoryError  추가한다. JVM 정지시에 힙덤프를 받아놓을수 있다.

- jvm 시작시에  verbose:class옵션을 추가한다. 클래스 로드, 언로드 상황을 볼수 있다.

7) Eclipse MAT을 사용해 힙덤프 내역을 분석한다.

반응형
Comments