JVM을 사용하다보면 자주 보는 에러들이 있다. 바로 OutOfMemory와 Memory Leak 관련 에러이다.
해당 에러의 원인은 대부분 JVM에서 사용하는 Heap Area의 메모리 용량이 부족하거나 혹은 메모리 누수(Memory Leak)가 있어 Garbage Collector가 정상적으로 메모리를 비워주지 못해 발생한다.
Garbage Collector(일명 GC) : 더이상 사용하지 않는 객체 등을 메모리에서 해제(삭제)하는 JVM의 작업
Memory Leak : 어떠한 로직이나 교착상태 때문에 사용했던 메모리가 해제 되지 않아 실질적으로 필요하지 않은 메모리 이지만 계속 점유하고있어 메모리가 손실되는 현상
- Memory Leak 관련 참고 : http://story.wisedog.net/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98-memory-leak%EB%9E%80/
이런 이슈를 해결하기 위해서는 필요한 만큼의 메모리 확보가 필요하다.
그렇다면 메모리 확보는 어떻게 해야할까?
우선 심플하게 생각해보자.
일단 내가 돌리고자 하는 서비스가 돌아갈만한 정도의 물리적인 메모리(RAM)가 필요하다.
간단하게 방법 1은 찾았다.
- 서버 인스턴스의 메모리 사양을 올린다.
자, 하드웨어적인 메모리는 해결했으니 이번엔 소프트웨어를 생각해보자.
일단 내가 돌릴 서버 어플리케이션이 잘 돌아갈만큼 OS에서 메모리를 적절히 할당 받아야 한다.
그렇다면 여기서 이야기할 Java 어플리케이션의 경우에는 메모리를 어디에서 관리할까?
정답은 Java Virtual Machine(JVM)의 Runtime Data Areas라는 영역에서 관리한다.
이 영역은 JVM이 OS위에서 실행되면서 할당받는 메모리 영역이다.
그 Runtime Data Areas 영역 안에 존재하는 Heap Area라는 부분에서 실질적인 메모리 할당을 받아 자바 어플리케이션을 구동한다.
그럼 Heap Area의 메모리 설정을 확인해보면 된다.
이렇게 방법 2도 찾았다.
- JVM Heap Area의 메모리 설정을 변경한다.
일단 이 글에서는 방법 1에대한 내용을 다루지는 않을 것이다.
이에 대한 내용은 추후에 기회가 된다면 업로드 할 예정이다.
방법 2를 위해서는 먼저 JVM Heap Area의 구조(Structure)를 알아야한다.
JVM의 Heap Area는 아래 그림처럼 구성되어있다.
위 메모리 구조를 보통 '힙 메모리'라고 부른다.
힙 메모리는 모든 Java 클래스 인스턴스 및 배열에 대한 메모리가 할당되는 런타임 데이터 영역이다.
JVM이 시작될 때 힙이 생성되며 애플리케이션이 실행되는 동안 크기가 증가하거나 감소할 수 있다.
힙 크기는 -Xms VM 옵션을 사용하여 지정할 수 있다.
또한 힙은 가비지 콜렉션 전략에 따라 고정 크기 또는 가변 크기일 수 있다.
-Xmx 옵션을 사용하여 최대 힙 크기를 설정할 수 있다.
기본적으로 최대 힙 크기는 64MB로 설정되어 있다.
그림과 같이 Heap Area의 구조는 크게 3가지로 나누어진다.
Young Generation | Eden | |
S0 | ||
S1 | ||
Virtual | ||
Old Generation | Tenured | |
Permanent Generation (Java 7 이전) | ||
Meta Space (Java 8 이후) |
Young Generation :
Old Generation :
Permanent Generation :
'개발관련' 카테고리의 다른 글
안정적인 서비스 운영을 위한 정리 (0) | 2019.10.01 |
---|---|
JVM Heap에 대한 좋은 글 링크(feat. Elastic search) (0) | 2019.09.08 |
[Java] jvm gc와 heap 메모리 체크 방법 (0) | 2019.08.12 |
JVM Heap Memory 관련 좋은 글 (0) | 2019.07.26 |
Local에서 사용하지 않는 Docker Image를 정리하는 커맨드 (0) | 2019.07.26 |