본문 바로가기
학습

가비지 컬렉터(Garbage Collector) - 2

코동이 2022. 10. 18.

개요


 앞서 가비지 컬렉터의 과정 및 사용 방법을 알아보았습니다. 이번 시간에는 Old 영역에서 가비지 컬렉터 알고리즘을 알아보겠습니다. 버전은 Java 7 기준입니다.

 

목차

Serial Collector
Parallel Collector
Parallel Old Collector
CMS Collector
G1 Garbage Collector

 

1. Serial Collector(-XX:+UseSerialGC)


  Serial collector는 단 하나만의 쓰레드를 사용하며 다른 쓰레드들과 통신할 일이 없기 때문에 효율적인 방법입니다. 하나의 단일 프로세서에 사용하기에 적합하며 대신에 멀티 프로세서의 이점은 이용할 수 없습니다. (약 100MB의 작은 데이터 부분의 어플리케이션의 멀티 프로세서에서는 가능합니다.)

 

 

 

2. Parallel Collector(-XX:+UseParallelGC)


 Parallel collector는 멀티 쓰레드를 사용해 가비지 컬렉터의 속도를 극대화하는 방법입니다. 따라서 serial collector보다 빠르게 객체를 처리할 수 있습니다. 메모리가 충분하고 코어 개수가 많을 때 유리합니다.

 

 Parallel compaction은 parallel collector가 major collection을 평행하게 수행하는 방식입니다. 만약, parallel compaction이 없다면, major collection은 단일 쓰레드를 사용하기 때문에 확장성에 한계를 가집니다.

 

 

3. Parallel Old Collector(-XX:+UseParallelOldGC)


 Parellel old collector는 앞서 설명한 paralell collector와 old 영역의 알고리즘에서 Sweep 대신 Summary를 사용합니다. 기존에 Mark-Sweep-Compaction은 단일 쓰레드를 사용하지만, Mark-Summary-Compaction은 멀티 쓰레드를 사용합니다.

 

 

4. CMS Collector(-XX:+UseConcMarkSweepGC)


 CMS Collector는 다른 쓰레드가 실행되고 있음에도 Mark, Sweep을 하여 STW(Stop-The-World)를 최소화하여 응답속도가 중요한 어플리케이션에 사용됩니다. Mark-Sweep-Compaction 방식은 가비지 컬렉터가 중간에 잠시 모든 쓰레드를 중단시켜야 하는 것과는 대조됩니다. 

 

 CMS Collector는 다음 4가지 과정을 거칩니다.

 

1. Initial Mark

클래스로더에서 가장 가까운 객체 중 살아있는 객체를 선택하고 중단합니다. 따라서 멈추는 시간이 짧습니다.

 

2. Concurrent Mark

앞서 선택된 살아있는 객체들이 참조하고 있는 객체들을 따라가면서 확인합니다. 이 작업 중에 다른 쓰레드는 중단되지 않습니다.

 

3. Remark

앞 단계에서 새롭게 추가되거나, 끊긴 참조를 확인합니다. 이 작업도 다른 쓰레드는 중단되지 않습니다.

 

4. Conccurent Sweep

가비지를 정리합니다. 이 작업도 다른 쓰레드는 중단되지 않습니다.

 

장점은 쓰레드 작업을 중단시키지 않기 때문에 응답속도가 빠르다는 것입니다.

 

단점은 다른 방식에 비해 많은 메모리와 CPU가 필요합니다. 또한 Compaction 과정이 없습니다.

가장 큰 문제는 Young Generation에서 Old Generation으로 넘어가는 promotion이 실패할 때입니다. young에서 old로 넘어가야 하지만, 공간 확보 시간이 충분하지 않을 때,  CMS Collector가 방지하려는 SWT이 발생합니다. 이 상황을 방지하기 위해서 Old Generation혹은 힙의 크기를 늘리거나 더 많은 백그라운드 쓰레드를 collector에 할당해야 합니다. 

 

 

 

5. G1 Garbage Collector(-XX:+UseG1GC)


 G1 garbage Collector는 기존에 물리적으로 구분하여 할당했던 young, old와 달리 일정 크기로 논리적으로 구분합니다, 바둑판 모양 region에 멀티 프로세스를 이용해 객체를 할당하고 제거합니다.

 

HotSpot에서 사용하던 방식과 마찬가지로 최초 객체들은 Eden에 할당하고 이후 Survivor로 이동과 소멸, 그리고 Old Region까지 생명주기를 가져갑니다.

 

Initial mark phase
G1 GC는 루트를 마크합니다. 

Root region scanning phase
G1 GC는 survivor region를 스캔합니다.

Concurrent marking phase
G1 GC는 동시에 전체 힙 영역에서 살아있는 객체를 찾습니다. 

Remark phase
STW 작업을 하며 하나의 사이클이 끝납니다. 

Cleanup phase
마지막 단계로 G1 GC는 region을 초기화하여 반납합니다

Garbage Collection Phases
G1 GC는 Snapshot-At-The-Begining(SATB) 알고리즘으로 마킹 사이클 시작 시 힙에 살아있는 객체들을 스냅샷으로 저장합니다. 살아있는 객체들은 스냅샷에 있는 살아있는 객체들과 마킹 사이클 이후 할당된 객체들로 이루어져 있습니다.

Young Garbage Collection
G1 GC는 eden 영역에 추가된 region들의 요청을 대부분 처리합니다. young garbage collection 동안, G1 GC는 eden과 survivor region 모두를 수집합니다. 이 과정에서 객체들은 새로운 곳으로 이동합니다. region의 목적지는 객체의 나이에 달려 있습니다. old 영역으로 옮기기 충분한 나이가 된다면 옮깁니다. 

Mixed Garbage Collection
동시 마킹 작업이 성공적으로 끝나면, G1 GC는 young garbage 에서 mixed garbage 작업으로 전환합니다. 제거될 eden과 survivor regions에 일부 old region을 포함시킵니다. G1 GC가 충분한 수의 old region을 수집하고나면, G1은 다음 마킹 주기가 완료될때까지 young garbage 수집으로 돌아갑니다. 

 

장점은 앞서 설명한 4가지 방식보다도 가비지 컬렉터의 속도가 가장 빠릅니다.

 

 

 

G1의 작동방식은 다음과 같습니다.

 

 

 

  • Java 8에서 개선된 가비지 컬렉터는?

Java 8에서는 Java 7의 힙 구조가 개선되었습니다. 다음 글에서 알아보겠습니다.

 

 

참고

https://www.perfmatrix.com/type-of-garbage-collector/

http://blog.ragozin.info/2011/07/hotspot-jvm-garbage-collection-options.html

https://docs.oracle.com/javase/9/gctuning/available-collectors.htm#JSGCT-GUID-45794DA6-AB96-4856-A96D-FDE5F7DEE498

https://d2.naver.com/helloworld/1329

반응형

'학습' 카테고리의 다른 글

객체지향과 4대 특성  (0) 2022.11.02
JVM의 구조  (0) 2022.10.21
가비지 컬렉터(Garbage Collector) - 1  (0) 2022.10.18
Array vs ArrayList  (0) 2022.10.17
HashSet은 내부가 어떻게 구현이 되어 있는가?  (0) 2022.10.15