JAVA의 메모리 영역
자바의 메모리 영역은 크게 Stack 영역과 Heap 영억으로 나뉘어 진다
Stack
- 정적으로 할당된 메모리 영역
- Stack에서는 기본타입의 데이터가 할당이되고 Heap 영역에 할당 된 Object 타입의 참조를 위한 값들이 Stack 영역에 할당
- Stack은 스레드가 생성될때마다 독립된 스택을 할당한다.
Heap
- 동적으로 할당된 메모리 영역
- 모든 Object 타입 및 new를 사용하여 객체를 생성하면 힙 영역에 저장
- 메모리의 낮은 주소에서부터 높은 주소로 할당이 이루어진다.
Garbage Collection이란?
- 더 이상 참조되지 않는 불필요한 메모리를 알아서 정리해주는 역할을 한다. 가비지 컬렉터가 주기적으로 메모리 누수를 방지하기 위해 메모리를 청소하는 과정을 Garbage Collection이라 한다.
가비지 컬렉션 과정
GC에 앞서 알아야하는 용어가 있는데 stop-the-world이다.
stop-the-world
- GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것
- stop-the-world가 발생하면 GC를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈추고 GC 작업이 완료된 이후에야 중단했던 작업을 재시작한다.
- 어떤 GC 알고리즘을 사용하더라도 stop-the-world은 발생하며 대개 GC 튜닝이란 stop-the-world의 시간을 줄이는 것을 의미한다.
GC는 크게 Young 영역과 Old영역, Perm영억으로 나뉘어 진다.
Young 영역
- 새롭게 생성한 객체의 대부분이 여기에 위치
- 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라진다.
- 이 영역에서 객체가 사라질떄 Minor GC가 발생한다고 말한다.
Young 영역의 구성
- 새로 생성된 객체 대부분은 Eden 영역에 위치
- Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.
- GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역에 객체가 계속 쌓임
- 하나의 Survivor 영역이 가득 차면 살아남은 객체를 다른 Survivor 영역으로 이동하여 하나의 Survivor 영역을 완전히 비워준다.
- 이런 GC과정을 통해 살아남은 객체는 Old 영역으로 이동
Old 영역의 GC
- 기본적으로 데이터가 가득 차면 GC를 실행
- GC의 방식에 따라 절차가 달라지며 JDK7의 기준으로 6가지 방식이있다.
- Serial GC
- Parallel GC
- Parallel Old GC
- Concurrent Mark & Sweep GC
- G1(Garbage First) GC
- ZGC
- JVM에서 절대 사용하면 안되는 것은 Serial GC이다.
1. Serial GC
- 가장 단순한 방식으로 GC를 싱글 스레드로 작동
- 싱글 스레드로 동작하여 그만큼 느리고 stop the world시간이 길다
- 사용하지 않는다.
2. Parallel GC
- Parallel GC는 Serial GC와 기본적인 알고리즘은 같다
- Young 영역의 GC를 멀티 스레드 방식을 사용하기 때문에, Serial GC에 비해 상대적으로 Stop The World 가 짧다.
- Old 영역에서는 멀티 스레드 방식을 사용하지 않는다.
3. Parallel Old GC
- JDK 5 update 6부터 제공한 GC 방식
- Old 영역에서도 멀티 스레드 방식을 사용한다.
- Parallel GC와 GC 알고리즘만 다르다.
4. CMS GC(Concurrent Mark Sweep GC)
- Stop The World로 Java Application이 멈추는 현상을 줄이고자 만든 GC
- 어플리케이션 스레드가 오랫동안 멈추지 않는다. (짧게 짧게 멈춘다)
CMS GC의 처리 순서
Inition Mark : 클래스 로더에서 살아 있는 객체 확인
Concurrent Mark : 위에서 확인한 객체에서 참고되고 있는 객체 확인
Remark : 위에서 새로 추가되거나 참고 끊어진 객체 확인
Concurrent Sweep : 정리
5. G1 GC
- CMS GC 를 개선하여 만든 GC로 기존 GC와는 다른 구조를 가진다.
- Heap 영역을 Young, Old 영역과 명확하게 구분하던 GC들과 다르게 물리적으로 구분하지 않는다.
- 개념적으로는 확실히 존재하지만, Heap 영역을 일정 크기의 region으로 구분하여 논리적으로 구분
- HotSpot VM(Virtual Machine)의 개념을 사용
- 가장 큰 장점은 성능면에서 어떤 GC 방식보다 빠르다.
6. ZGC
- ZGC는 JDK 11부터 실험적으로 도입
- 대기 시간이 낮은 확장 가능한 GC이다. ZGC는 모든 종류의 비싼 작업을 동시에 작업하며, 애플리케이션 스레드의 실행을 중지하지 않는다는 특징
- 10ms 미만의 짧은 대기 시간이 필요하거나 테라 바이트 큐모의 매우 큰 heap을 사용하는 애플리케이션을 위한 GC
ZGC의 목표
- 정지 시간이 최대 10ms를 초과하지 않음
- Heap의 크기에 증가하더라도 정지 시간이 증가하지 않음
- G1보다 애플리케이션 처리율이 15% 이상 떨어지지 않음
ZGC는 좀더 공부가 필요한 부분이라고 생각이 들고 아직 제대로 이해 못했기에 이런 GC만 있다 정도만 기억하고 다음에 ZGC에 대해 포스팅하도록 해봐야겠다.