Generation Garbage Collection
가비지 컬렉션이란?
- 동적으로 할당한 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능
- Java에서 개발자가 프로그램 코드로 메모리를 명시적으로 해제하지 않기 때문에, 메모리 누수 방지를 위해 가비지 컬렉터는 더 이상 필요 없는 객체를 찾아서 지우는 역할을 한다.
동적으로 할당된 메모리 영역 == Heap 모든 Object타입의 데이터 할당 Heap 영역의 Object를 가리키는 참조변수가 Stack에 할당 — 정적으로 할당된 메모리 영역 == Stack 원시 타입의 데이터가 값과 함께 할당 Heap 영역에 생성된 Object 타입의 데이터 참조 값 할당
Garbage Collector의 동작 과정
- Garbage Collector가 Stack의 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
Mark
- Reachable Object가 참조하고 있는 객체도 찾아서 마킹한다.
Mark
- 마킹되지 않은 객체를 Heap에서 제거한다.
Sweep
가설(전제조건) Weak generation hypothesis
- 대부분의 객체는 금방 접근 불가능
unreachable
상태가 된다. - 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
이 가설의 장점을 최대한 살리기 위해서
HotSpot VM에서는 물리적 공간을 크게 2개로 나눈다.
Young Generation 영역
- 새롭게 생성한 객체의 대부분이 위치하는 곳
- 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 많은 객체가 Young영역에 생성되었다가 사라진다.
- 객체가 사라질 때 Minor GC가 발생한다고 말한다.
Old Generation 영역
- 접근 불가능 상태로 되지 않아 Young영역에서 살아남은 객체가 여기로 복사된다.
- 대부분 Young영역보다 크게 할당한다. 크기가 큰만큼 Young영역보다 GC가 벅게 발생한다.
- 객체가 사라질 때 Major GC가 발생한다고 말한다.
- Permanent Generation 영역은 Method Area라고도 한다.
- 객체나 억류된 문자열 정보를 저장하는 곳
- Old영역에서 살아남은 객체가 영원히 남아 있는 곳은 아니다.
- 이 영역에서 GC가 발생해도 Major GC의 횟수에 포함된다.
Old영역의 객체가 Young영역의 객체를 참조한다면?
- Old영역에는 512byte의 chunk로 되어있는 card table이 있는데, 카드테이블에는 Old영역 객체가 Young영역 객체를 참조할 때마다 정보가 표시된다.
- Young영역의 GC를 실행할 때 Old영역에 있는 모든 객체의 참조를 확인하지 않고, 이 카드 테이블만 뒤져서 GC 대상인지 식별한다.
- 카드테이블은 write barrier를 사용하여 관리한다.
동작 방식
- Stop the world
- Mark and Sweep
Stop the world
stop-the-world
: GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것.
- 실행시 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춘다.
- GC작업이 끝나면 중단했던 작업을 다시 시작한다.
- 모든 GC알고리즘은 stop-the-world
를 발생시킨다.
Mark and Sweep
Mark
: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
- stop-the-world
로 모든 작업을 중단시키면, GC는 스택의 모든 변수나 Reachable 객체를 스캔하면서 각각 어떤 객체를 참고하고 잇는지 탐색한다. 그러면서 사용되고 있는 메모리를 식별하는 과정을 Mark
라 한다
Sweep
: Mark 단계에서 사용되지 않는다고 분류된 메모리를 해제하는 작업
- Mark
가 되지 않은 객체들을 메모리에서 제거하는 과정
Young영역의 구성
- Young영역은 객체가 제일 먼저 생성되는 곳이다.
Eden영역
/Survivor영역
(2개)로 이루어진다.
처리 절차
Eden
: 새로 생성한 대부분의 객체가 생성된 위치Eden
에서 GC가 한번 발생한 후 살아남은 객체는Survivor
영역 중 하나로 이동된다Eden
에서 GC가 발생하면 이미 살아남은 객체가 존재하는Survivor
영역으로 객체가 계속 쌓인다- 하나의
Survivor
영역이 가득차게 되면 그 중에서 살아남은 객체는 다른Survivor
영역으로 이동한다. 가득 찬Survivor
영역은 아무 데이터도 없는 상태가 된다. -
이 과정을 반복하다가 계속해서 살아남아있는 객체는
Old
영역으로 이동한다 Survivor
영역 중 하나는 반드시 비어있는 상태로 남아있어야 한다.- 만약 두
Survivor
영역에 모두 데이터가 존재하거나 두 영역 모두 사용량이 0이면 시스템이 정상적인 상황이 아니라고 보면 된다
Garbage Collector 종류
- Serial GC
- GC를 처리하는 스레드가 1개다
- CPU 코어가 1개만 있을 때 사용하는 방식이다
- Mark-Compact collection 알고리즘 사용
- Parallel GC
- GC를 처리하는 스레드가 여러 개다
- Serial GC보다 빠르게 객체를 처리할 수 있다
- 메모리가 충분하고 코어의 개수가 많을 때 사용하면 좋다
- Concurrent Mark Sweep GC (CMS GC)
Stop the world
를 줄이는 GCstop the world
시간이 짧아서, 애플리케이션의 응답 시간이 빨라야 할 때 사용한다- 다른 GC방식보다 메모리와 CPU를 더 많이 사용한다
- Compaction 단계가 제공되지 않는다
- G1 GC
- 각 영역을 Region 영역으로 나눈다
- GC가 일어날 때 전체영역(Eden, Survival, Old generation)을 탐색하지 않는다
- 바둑판의 각 영역에 객체를 할당하고 GC를 실행한다
- 해당 영역이 꽉 차면 다른 빈 영역에 객체를 할당하고 gC를 실행한다
- STW 시간이 짧다
- Compaction을 사용한다
reference
Java Garbage Collection [Java] Garbage Collection(가비지 컬렉션)의 개념 및 동작 원리 (1/2) [10분 테코톡] 👌던의 JVM의 Garbage Collector