* GC (Garbage Collector)

> 메모리 할당

> 사용중인 메모리 인식

> 사용하지 않는 메모리 인식


* GC 의 종류

> Minor GC

: Young 영역에서 발생하는 GC

> Major GC

: Old 영역이나 Perm 영역에서 발생하는 GC

> 위 2가지가 어떻게 상호 작용하느냐에 따라 GC 작동 방식에도 차이가 생기며, 성능에도 영향을 준다.
    따라서, HotSpot JVM 에서는 TLABs (Thread-Local Allocation Buffers) 라는 것을 사용하여, 다른 쓰레드에 영향을 주지 않는 할당 작업이 가능하다


* 5가지 GC 방식

> Serial Collector

> Parallel Collector

> Parallel Compacting Collector

> Concurrent Mark-Sweep (CMS) Collector

> Garbage First (G1) Collector (Java 7 ~)


 구분

 설정 Option

 Young Generation Collection

 Old Generation Collection

 Serial Collector

 -XX:+UseSerialGC 

 Serial

 Mark-sweep-compact

 Parallel Collector

 -XX:+UseParallelGC

 Parallel

 Mark-sweep-compact

 Parallel Compacting Collector

 -XX:+UseParallelOldGC

 Parallel

 Mark-summary-compact

 CMS Collector

 -XX:+UseConcMarkSweepGC

 Parallel

 Concurrent Mark-Sweep

 G1 Collector

 -XX:+UseG1GC

 

 



* Serial Collector


> Young 영역과 Old 영역이 Serial 하게 처리되며 하나의 CPU 를 사용한다

(이 동작을 수행하는 것을 "Stop-The-World (STW)" 라고 표현한다. Collection 수행동안 App 수행이 정지된다)


1. 살아 있는 객체들은 Eden 영역에 있다

2. Eden 영역이 꽉차게 되면 To Survivor 영역으로 살아 있는 객체가 이동한다
    (너무 큰 객체는 바로 Old 영역으로 이동한다. From Survivor 영역에 살아있는 객체는 To Survivor 영역으로 이동한다)

3. To Survivor 영역이 꽉 찼을 경우, Eden 영역이나 From Survivor 영역에 남아있는 객체들은 Old 영역으로 이동한다)

4. Old, Perm 영역에 있는 객체들은 Mark-sweep-compact 콜렌션 알고리즘을 따른다
    (= 사용되지 않는 객체를 mark 하고 삭제 후에 한 곳으로 모으는 알고리즘)

1) Old 영역으로 이동된 객체들 중 살아 있는 객체를 식별 (mark)

2) Old 영역의 객체들을 훑는 작업을 수행하여 쓰레기 객체를 식별 (sweep)

3) 필요 없는 객체들을 지우고 살아있는 객체들을 한 곳으로 모은다 (compaction)


* Parallel Collector (=Throughput Collector)

> 다른 CPU가 대기 상태로 남아있는 것을 최소화하는 것이 목적이다
    : 많은 CPU 를 사용하기 때문에 GC 의 부하를줄이고 App 의 처리량을 증가시킬 수 있다

> Sweep 단계에서 Single Thread 가 Old 영역 전체를 훑는 것은 Serial Collector 와 동일하다.
    하지만, Summary 단계는 Multi Thread 가 Old 영역을 분리하여 훑는다


* Parallel Compacting Collector (Java 5 ~)

> Old 영역의 GC 는 아래 3단계를 거친다

1. Marking

: 살아 있는 객체를 식별하여 표시해 놓는 단계

2. Summary

: 이전에 GC를 수행하여 Compaction 된 영역에 살아 있는 객체의 위치를 조사하는 단계

3. Compaction

: 컴팩션을 수행하는 단계. 수행 이후에는 컴팩션된 영역과 비어 있는 영역으로 나뉜다

> -XX:ParallelGCThreads=n 을 통해 스레드 개수를 조정할 수 있다


* CMS (Concurrent Mark-Sweep) Collector (= Low-latency Collector)

> Heap 메모리 영역이 클 때 적합

> Old 영역의 GC 는 아래 단계를 거친다

1. Initial Mark (STW)

: 매우 짧은 대기 시간으로 살아 있는 개체를 찾는 단계

2. Concurrent Marking

: 서버 수행과 동시에 살아 있는 객체에 표시를 해 놓는 단계

3. Remark (STW)

: Concurrent Marking 단계에서 표시하는 동안 변경된 객체에 대해서 다시 표시하는 단계

4. Concurrent Sweep

: 표시되어 있는 쓰레기를 정리하는 단계

> GC 는 CMS 가 빠르지만, 이후 메모리 할당은 Parallel 이 빠를 수 있다


* Garbage First (G1) Collector (Java 7 ~)

> 바둑판 모양으로 region 이 있으며, 각 region 은 1~32MB 의 크기를 가진다

> Eden, Survivor, Old 영역의 역할을 변경해 가면서 한다

1. 몇 개의 구역을 선정하여 Young 영역으로 지정한다

2. 객체가 생성되면서 Young 영역에 데이터가 쌓인다

3. Young 영역이 꽉차면 GC 를 수행한다

4. GC 를 수행하면서 살아있는 객체들만 Survivor 구역으로 이동시킨다

5. 몇번의 GC 에도 Survivor 영역에 객체가 살아있으면 Old 영역으로 이동시킨다

> Old 영역의 GC 는 아래 단계를 거친다

1. Initial Mark (STW)

: Old 영역에서 Survivor 영역의 객체를 참조하고 있는 객체들을 표시한다

2. Root Region Scanning

: Old 영역 참조를 위해서 Survivor 영역을 훑는다

3. Concurrent Marking

: 전체 Heap 영역에서 살아있는 객체를 찾는다. 이때, Young GC 가 발생하면 잠시 멈춘다

4. Remark (STW)

: Heap 에 살아있는 객체들의 표시작업을 완료한다.
: 이 때, SATB (Snapshot-At-The-Begining) 알고리즘을 사용하며, 이는 CMS GC 보다 빠르다

5. Clean Up (STW)

: 살아있는 객체와 비어 있는 구역을 식별하고 필요없는 개체들을 지운다. 그리고 비어 있는 구역은 초기화 한다

6. Copying (STW)

: 살아있는 객체들을 빈 구역으로 모은다



* 출처 : https://www.oracle.com/java/technologies/javase/javase-core-technologies-apis.html


* 참고 : https://blog.naver.com/lovemycat/221929601589


'SW > ::: Java' 카테고리의 다른 글

JDK 구성 요소  (0) 2021.01.02
JVM (메모리 구조)  (0) 2020.10.10
JIT Compiler  (0) 2020.10.10
Class Loading  (0) 2020.10.10
HotSpot VM  (0) 2020.10.10

+ Recent posts