모르는게 많은 개발자

[JAVA] Garbage Collection 정리(과정/방식) 본문

자바

[JAVA] Garbage Collection 정리(과정/방식)

Awdsd 2020. 6. 11. 20:33
반응형

저번 포스팅에서 JVM에 대해 알아보았다. 이번에는 자바에서 정말 많이 중요한 기능이라 생각하는 Garbage Collection에 대해 알아보았다.


1. Garbage Collection이란?

자바 어플리케이션을 실행하게되면 여러 객체들이 생성되게 된다. 여기서 어플리케이션이 실행되다보면 이제는 쓰지 않는 객체가 나오기 마련이다. 이러한 객체를 계속 가지고 있으면 메모리 낭비가 되게 된다. 프로그래머가 명시적으로 객체를 null로 하여 해제할 수 있지만 JVM에서 더이상 쓸모없는 객체를 알아서 제거해주는 기능을 Garbage Collection이라고 한다.


2. Garbage Collection 조건/구조

GC란 필요없는 객체를 회수하는 작업이란 것을 알았다.

JVM이 GC를 수행하게 되면 GC를 수행하는 쓰레드를 제외한 모든 쓰레드를 중지한다. 이것을 stop-the-world라고 한다. 

GC튜닝은 stop-the-world 시간을 줄이는 것을 의미한다.

 

Garbage Collection 전제 조건
  • 대부분의 객체는 금방 접근 불가능 상태(unreachable)가 됨
  • 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재
  • 위의 전제 조건들을 Weak Generational Hypothesis라고 함

가상 머신은 Garbage Collection을 위해 힙 영역을 물리적으로 Young, Old 영역으로 나눴다.

Young 영역
  • 새롭게 생성한 객체의 대부분이 여기에 위치
  • 대부분 객체는 금방 접근 불가능 상태(unreachable)이 되므로 Young영역에서 생성되었다가 사라짐
  • Young영역에서 발생하는 GC를 MinorGC라함
Old 영역
  • 접근 불가 상태가 되지 않아 young영역에서 살아남은 객체가 복사되는 영역
  • 대부분 young영역보다 크게 할당, young보다 GC가 적게 발생(영역이 꽉차야 GC 발생)
  • 객체가 사라질 때 major GC 또는 Full GC라 부른다.

Young 영역은 Eden영역, Survivor영역 2개로 총 3개로 나뉘어져있다.


3. Garbage Collection 과정

위와 같이 Garbage Collection을 수행하기 위해 Young과 Old 영역으로 분리된 것을 알았다. GC 과정을 보자. 

Young 영역의 GC 과정

GC발생

Young 영역은 Eden영역 1개, Survivor영역 2개로 구성되어 있다.

  1. 새로운 객체는 Eden영역에 생성된다.
  2. Eden영역이 꽉차게 되면 Minor GC발생.
  3. JVM은 Minor GC를 수행하기 위해 stop-the-world 상태로 만듦
  4. 더 이상 참조 되지 않는 객체들을 선별
  5. 살아남은 객체들은 Eden에서 From  Survivor로 복사 후 Eden에 존재하던 객체들 비움
    -> From Survivor이 가득찰때까지 반복
  6. From Survivor이 가득차고 Eden이 또 가득차 GC수행되면 Eden과 Survivor에서 살아남은 객체를 To Survivor로 이동한 후 Eden, From Survivor에 있던 객체들 비움
  7. 1~6 과정을 반복
  8. 반복하는 과정에서 Survivor간 객체가 이동하면 객체의 Age값이 증가한다. 이 Age값이 일정 값이상이면 Old영역으로 이동

이후 Old영역으로 객체들이 이동하면서 Old영역이 가득차면 major GC(Full GC)를 수행하여 사용하지 않는 객체를 제거한다.


4. Garbage Collection 방식

GC를 하는 방식에는 여러가지 방식이 있다. 그 방식들을 한번 살펴보자.

 

Serial GC

Serial GC는 Young영역은 위에 설명한 과정처럼 진행하고 Old영역에서 Mark-Sweep-Compact 알고리즘을 적용한 방식이다.

Mark-Sweep-Compact 알고리즘
GC가 진행될 때
1. Old영역의 객체들 중 사용되지 않는 객체 식별(Mark)
2. 사용되지 않는 객체 제거(Sweep)
3. 객체 제거후 여기 저기 있는 살아남은 객체들을 앞에서부터 차례로 채워나간다(Compaction)

Serial GC

Serial GC는 이러한 과정을 일련의 순서로 처리한다. 그래서 적은 메모리와 CPU코어 개수가 적을 때 적합하다.

 

Parallel GC

Parallel GC는 Serail GC와 방식은 비슷하지만 일련의 순서로 처리하는 것을 병렬로 처리하는 것에 차이가 있다.

그래서 Parallel GC는 메모리가 충분하고 코어의 개수가 많을 때 유리하다. Throughpiut GC라 불린다.

Serial GC VS Parallel GC

 

Parallel Old GC(Parallel Compacting GC)

Parallel GC의 Old 영역 GC 알고리즘인 mark-sweep-compact 대신 mark-summary-compact알고리즘을 사용한 방식이다.
summary 단계에서는 이미 GC가 수행된 영역에서 별도로 살아있는 객체를 식별한다.

 

Concurrent Mark & Sweep GC(이하 CMS)

CMS방식은 initial mark, concurrent mark, remark, concurrent sweep 4개의 과정을 거친다.

1. Initial mark : 짧은 시간동안 살아있는 객체를 판별 (stop-the-world 적용)

2. Concurrent mark : Initial mark에서 확인한 객체들이 참조하고 있는 객체들을 따라가며 확인
특징은 이 과정에서 stop-the-world는 적용되지 않고 진행

3. Remark : Concurrent mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인 (stop-the-world 적용)

4. Concurrent Sweep : 쓰레기 객체 정리
여기서도 stop-the-wrold가 적용되지 않고 진행

CMS

CMS 방식은 stop-the-world시간이 매우 짧다. 그래서 애플리케이션 응답속도가 중요할때 사용하며 Low latency GC라고도 불린다.
하지만 다른 GC보다 메모리와 CPU를 더 많이 사용하고 compaction단계가 제공되지 않는다.


참고

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

https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html

반응형
Comments