본문 바로가기

Java/JVM

Garbage Collection

출처 : d2.naver.com/helloworld/1329

 

가비지 컬렉션 과정

GC 를 알기 전 stop-the-world 를 알아보자

stop-the-world 란 GC 를 실행하기 위해 JVM이 어플리케이션을 멈추는 것이다.

 

stop-the-world 가 발생하면 GC 실행 스레드를 제외하고 모든 스레드가 작업을 멈춘다.

GC가 완료된 후에 다시 시작한다. 

대개의 GC 튜닝이란 이 stop-the-world 시간을 줄이는 것이다.

 

자바는 개발자가 코드로 메모리를 명시적으로 해제하지 않기 때문에,

가비지 컬렉터가 알아서 객체를 찾아 지운다.

 

HotSpot VM 에서는 크게 2가지로 물리적 공간을 나눴다.

Young 영역과 Old 영역이다.

 

 

Young 영역: 새롭게 생성된 객체는 대부분 여기에 위치. 대부분의 객체가 금방 접근 불가 상태가 되기때문에

거의 Young 에서 생성되었다가 사라진다. 여기서 객체가 사라질때 Minor GC가 발생한다.

 

Old 영역: Young 에서 살아남은 객체가 여기로 온다. 대부분 Young 영역보단 크게 할당하고

크기가 큰 만큼 GC는 적게 발생한다. 이 영역에서 객체가 사라질때 Major GC(Full GC)가 발생한다.

 

 

Perm 영역은 Method Area 라고도 하는데 객체나 문자열 정보를 저장하는곳이다.

이 영역도 GC 가 발생하면  Major GC 가 된다.

 

Young 영역

 

Young 영역은 크게 3개의 영역으로 나뉜다.

 

  • Eden 영역
  • Survivor 영역 (2개)

새로 생성된 객체는 Eden 영역에 있다가,

Eden 영역에서 GC가 발생 후 살아남은 객체는 Survivor 영역으로 간다.

Survivor 영역에 객체가 계속 쌓이다가

하나의 Survivor 이 가득 차면, 그 중에서 살아있는 객체를 다른 Survivor로 이동시키고

가득찬 Survivor 영역은 비워준다.

이 과정을 반복하다가 계속 살아 있는 객체는 Olde 영역으로 보내게 된다.

 

* Survivor 영역 중 한 곳은 항상 비어져 있어야 한다.

 

이미지 처럼 Survivor 에서 계속 살아남는 객체는 Old 영역으로 보내게 된다.

 

Old 영역

Old 영역은 기본적으로 데이터가 가득차면 GC 를 한다.

GC에 처리 방식이 다르게 있다.

 

  • Serial GC
  • Parallel GC
  • Parallel Old GC
  • Concurrent Mark & Sweep GC (CMS)
  • G1(Garbage First) GC

 

Serial GC

 

mark-sweep-compact 알고리즘을 사용한다.

Old 영역에 살아있는 객체를 Mark 하고 힙의 앞 부분 부터 확인하면서

살아있는것만 남긴다 (Sweep)

마지막엔 객체들이 연속되게 쌓이게 힙의 앞 부분부터 채워서 객체가 존재하는 부분과 

존재하지 않는 부분을 나눈다 (Compact)

 

Parallel GC

 

Parallel 과 Serial 은 기본적인 알고리즘은 같다.

대신 Parallel 은 GC 를 처리하는 스레드가 여러개다.

Serial 보다 빠르게 객체를 처리할수있다.

 

Parallel Old GC

 

mark-summary-compaction 알고리즘을 사용한다.

sweep 단계에서 힙의 앞부분 부터 확인 하던 mark-sweep-compact 알고리즘과 비교했을때

summary 는 GC 를 수행한 영역에 대해서만 별도로 살아있는 객체를 식별한다는 점이 다르다.

 

CMS GC

 

 

Serial GC 와 비교했을때 상당히 복잡한 GC 과정을 거친다.

 

초기 Initial Mark 에서는 클래스로더에서 가장 가까운 객체 중 살아있는 객체만 찾고

(멈추는 시간이 매우 짧다)

Concurrent Mark 에서 방금 살아있다고한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다.

이 단계는 다른 스레드들이 실행 중인 상태에서 동시에 진행된다.

 

그 다음 Remark 에서 Concurrent Mark 에서 참조가 끊긴 객체를 확인하고

마지막으로 쓰레기를 정리하는 작업을 진행한다.

이 작업도 다른 스레드가 실행되고 있는 상황에서 진행된다.

 

stop-the-world 시간이 매우 짧다.

응답 속도가 매우 중요할때 사용한다.

 

대신 단점이 있는데,

다른 GC 보다 메모리 사용이 크고 , Compaction (힙의 앞부분 부터 객체를 채워 주는)이 기본적으로 제공되지 않는다.

 

G1 GC

 

앞서 본 Young 과  Old 는 잊어버리자

 

G1 GC 는 바둑판의 영역에 객체를 할당하고

GC 를 실행한다. 그러다 해당 영역이 꽉차면 , 

다른 영역에서 객체를 할당하고 GC 를 실행한다.

즉, 지금까지 봤던 Young 에서 Old 로 이동하는 단계가 사라진 GC 방식이라고 볼 수 있다.

CMS 를 대체 하기 위해 만들어 졌다.

 

어떤 GC 보다 가장 빠르다.

 

'Java > JVM' 카테고리의 다른 글

Stack - 메모리 관리  (0) 2021.02.04
JVM 과 JIT 컴파일러  (0) 2021.02.04
컴파일러  (0) 2021.02.04
JVM 이란?  (0) 2019.11.11