Garbage Collection: JVM에서 동적 할당한 메모리 중, 사용하지 않는 메모리 객체를 메모리에서 주기적으로 삭제하는 행위
자바 애플리케이션을 실행할 때 사용되는 데이터를 적재하는 메모리 영역인 Runtime Data Area는 총 5가지 영역인 Heap Area, Stack Area, Native Method Area, PC Register, Method Area으로 나뉜다.
그 중 가비지 컬렉션이 담당하는 영역은 Heap Area로 클래스, 인스턴스, 배열 타입 등의 Reference Type의 데이터가 저장되는 곳이다.
GC(Garbage Collection)는 Heap 영역 내에서 더 이상 사용되지 않는 데이터에 할당된 메모리를 Garbage Collector가 해제시켜 주는 것이다.
GC의 대상
1. 객체가 Null인 경우
2. 블럭 내에서 객체가 생성되고 해당 블럭의 실행이 종료될 경우
3. 상속받은 부모 객체가 Null이 되는 경우
위의 3가지 중 하나라도 충족할 경우 GC의 대상이 된다.
세 항목 모두 Heap에 저장된 데이터가 참조 되지 않는다 라는 공통점을 지닌다. 즉 heap 내 데이터의 참조/미참조 여부에 따라 GC 대상이 결정되는 것을 알 수 있다.
GC의 메모리 해제 과정
데이터가 GC 대상이 되면 해당 데이터에 할당된 메모리가 해제된다. GC 중에 발생하는 메모리 해제 과정에 대해 알아보자.
GC의 메모리 해제 과정은 3단계로 나뉜다.
1. Marking
- 먼저 사용중인 객체와 미사용중인 객체를 구분하기 위한 프로세스 마킹이 호출된다.
- 이 때 참조되는 객체 / 참조되지 않는 객체를 마킹을 통해 구분한다. 예시에서는 편의를 위해 색깔로 구분해 놓은 것을 알 수 있다.
- 모든 객체가 마킹 단계를 거치기 때문에 많은 시간이 소요되는 특징이 있다.
2. Sweep(Normal Deletion)
- Sweep 단계에서는 마킹된 객체에 할당되었던 메모리를 반환한다.
- 객체에 할당된 메모리가 반환되면 그림과 같이 비게 된다.
3. Compacting
- Sweep 단계를 거치게 되면 필요 없는 메모리가 반환됨에 따라 메모리 공간이 단편화되는 현상이 발생한다.
- 이 때 분산된 메모리 공간을 성능 향상을 위해 하나로 합치는 과정을 거치는데, 이를 Compaction(압축)이라고 한다.
- Compaction을 통해 새로운 큰 크기의 메모리 공간이 형성되고 메모리 할당이 수월해진다.
Generational Garbage Collection
Garbage Collection은 효율적인 데이터 관리 및 처리를 위해 객체를 생존 기간 별로 분류하여 관리한다. 이를 Generational Garbage Collection이라고 한다.
Garbage Collection은 기본적으로 Weak Generational Hypothesis에 기반한다.
Weak Generational Hypothesis
1. 신규로 생성한 객체는 대부분 사용하지 않는 상태가 되어 GC에 의해 메모리가 회수된다. 즉 생존기간이 짧다.
2. 오래된 객체에서 신규 객체로의 참조 빈도는 낮기 때문에 참조가 끊어짐에 따른 GC에 의한 메모리 회수의 가능성 또한 낮다.
요약: 객체는 대부분 일회성이며 메모리에 오랫동안 남는 경우가 드물다. 신규 생성 객체는 사라질 확률이 높고, 오래된 객체일수록 사라질 확률이 낮으므로 생존 기간에 따라 메모리 할당 영역을 나눠 효율적인 메모리 관리를 하는 것이다.
1. Young 영역(Young Generation 영역)
- 대부분의 신규 생성 객체가 Young 영역에 생성된다. 생성된 신규 객체는 대부분 GC로 인해 메모리 회수가 되고 접근 불가 상태가 된다.
- Young 영역에서 발생하는 GC를 Minor GC라고 한다.
2. Old 영역(Old Generation 영역)
- 접근 불가능 상태가 되지 않아 Young 영역에서 살아남은 객체들은 Old 영역으로 복사된다.
- 일반적으로 Young 영역보다 크기가 크게 할당되고 크기가 큰 만큼 GC는 Young 영역에 비해 덜 발생한다.
- Old 영역에서 발생하는 GC를 Major GC라고 한다.
3. Permanent 영역(Meta Space)
- Method 영역이라고도 불리며 JVM이 클래스와 메서드 정의를 위한 메타 데이터를 저장하는 곳이다.
🤓자바 7 이후로 PermGen(Permanent Generation)은 Metaspace로 변경되었다.
Generational Garbage Collection 과정
1. 신규 객체가 생성되면 eden space에 저장된다.(Young Generation 영역에 할당)
2. eden space가 가득 차면 Minor GC가 시작된다.
3. Marking을 통해 비참조 객체는 Clear 처리되고 참조 객체는 survivor space S0로 이동된다. (객체는 이동하면서 age + 1 처리가 된다.)
4. 다음 Minor GC에서는 기존 S0에 존재하던 객체와 신규 참조(생성) 객체가 S1으로 이동된다. 이 때 주의할 점은 survivor space 간 이동하는 기존의 객체도 age + 1 이 된다.
5. Minor GC가 반복되고 객체의 복사가 반복된다. 해당 과정에서 살아남은 객체의 age가 정해진 기준 age(Threshold: 문지방)을 넘게 되면 Young 영역에서 Old 영역으로 복사된다. Young 영역에서 Old 영역으로의 복사 과정을 Promotion(승급)이라고 한다.
6. Old 영역의 메모리가 가득 차서 부족할 경우 Major GC가 발생하고 Old 영역 내의 Compaction(압축)이 이루어진다.
GC 알고리즘 종류
자바가 발전함에 따라 heap의 크기 또한 커지게 되었다. heap의 크기 증가에 따란 지연(suspend) 및 오버헤드 또한 증가하게 되었다.
따라서 GC에 의한 성능 저하를 줄이기 위해서 여러 GC 알고리즘 또한 발전하였다.
1. Serial GC
- 서버의 CPU 코어가 1개일 때 사용되는 GC 알고리즘이며 가장 단순한 GC이다.
- GC 처리가 싱글 스레딩이라서 stop-the-world 시간이 가장 길다는 단점이 있다.
- Minor GC 시 mark-sweep, Major GC 시 mark-sweep-compact를 사용한다.
- 실무에서는 잘 쓰이지 않는다.
2. Parallel GC
- Java 8에서의 기본 GC이다.
- 모든 GC를 싱글 스레딩으로 처리하던 Serial GC와는 달리 Minor GC는 멀티스레딩으로 처리한다.(Major GC는 싱글스레딩으로 처리한다.)
3. Parallel Old GC(Parallel Compact Collector)
- Parallel GC를 개선한 버전이다.
- Parallel GC와는 다르게 Old 영역의 Major GC도 멀티스레딩으로 처리한다.
- 새로운 방식인 mark-summary-compact를 사용한다.
4. CMS GC(Concurrent Mark Sweep)
- stop-the-world를 최소화하기 위해서 애플리케이션 스레드와 GC 스레드를 동시에 수행한다.
- GC와 애플리케이션 스레드를 동시에 처리하기 때문에 GC과정이 복잡하고 CPU 사용량이 높다.
- 메모리 파편화가 발생한다는 단점이 있으며 Java 9부터 deprecated 됐으며 Java 14에서는 사용 중지되었다.
5. G1 GC
- CMS GC를 대체하기 위해 jdk7 버전에서 최초로 release 되었다.
- Java 9+ 버전의 default GC이며 heap 메모리가 4GB 이상일 때 사용이 권장된다.
- 기존의 heap에서 정적으로 Young, Old 영역을 나누어 메모리를 할당했던 것과 달리 전체 heap영역을 region이라는 영역으로 나눈다.
- heap을 region으로 분리하여 상황에 따라 eden, survivor, old 등의 역할을 동적으로 부여한다.
🤓G1 GC는 이전 GC들과 다르게 일일이 메모리를 탐색하여 객체를 할당 및 제거하지 않는다. 메모리가 많이 차있는 region을 우선적으로 GC처리한다.
6. Shenandoah GC
- Java 12에 release 된 레드햇에서 개발한 GC이다.
- 기존 CMS가 가진 단편화, G1 GC가 가진 pause의 문제를 보완하였다.
- 강력한 concurrency와 가벼운 GC로직을 지니고 있으며 일정한 pause 시간을 가진다.
7. ZGC(Z Garbage Collector)
- Java 15에 release 되었으며 대량의 메모리(8mb ~ 18tb)를 low latency로 처리를 위해 사용되는 GC이다.
- G1 GC의 region처럼 ZPage라는 영역을 사용한다. Region은 크기가 고정인 데에 비해 ZPage의 크기는 2mb 배수로 동적으로 할당된다.
- 힙 크기가 증가하더라도 stop-the-world의 시간이 10ms를 넘지 않는다는 장점이 있다.
References
☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리
Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객
inpa.tistory.com
https://gyoogle.dev/blog/computer-language/Java/Garbage%20Collection.html
Garbage Collection | 👨🏻💻 Tech Interview
Garbage Collection Goal Garbage Collection의 역할에 대해 설명할 수 있다. Garbage Collection의 메모리 해제 과정을 3단계로 설명할 수 있다. Generational Gabage Collection에 대해 설명할 수 있다. Generational Garbage Colle
gyoogle.dev
'Java' 카테고리의 다른 글
[Java] Object 클래스 (0) | 2024.04.07 |
---|---|
[Java] Thread(스레드) (1) | 2024.04.07 |
[Java] Stream(스트림) (1) | 2024.04.06 |
[Java] Interned String (0) | 2024.04.06 |
[Java] Record(레코드) (0) | 2024.04.06 |