Post

자바의 가비지 컬렉터 종류

개론

자바의 가비지 컬렉션 알고리즘은 기본적으로 Stop The World 이벤트를 전제하에 구성된다.

Stop The World 이벤트 발생 시 모든 스레드가 일시 정지되고, 성능에 치명적이기 때문에 이를 개선하기 위해 다양한 방식의 GC가 개발되고 있다.

자바에는 어떤 GC가 존재하는지, 종류별 특징은 무엇인지 알아보자

GC의 종류

Serial GC

GC를 처리하는 스레드가 한개이며 GC 수행 시 Stop the world, 모든 어플리케이션 스레드가 정지된다.

우리가 기본적으로 배운 참조된 객체 식별 후 메모리를 정리하는 방식(mark-sweep-compact)이 사용된다.

메모리 용량이 작고 CPU 코어 갯수가 적을 때 사용하기 적합하다.

Parallel GC(=Throughput GC)

Parallel GC는 Serial GC와 기본적인 작동 방식은 같지만 GC를 처리하는 쓰레드가 여러 개여서 Serial GC보다 더 나은 성능을 보여준다.

메모리 용량이 어느 정도 충분하고 다중 코어 CPU를 사용할 때 적합하다.

CMS(Concurrent Mark Sweep) GC (=Low Latency GC)

helloworld-1329-5

stop the world 시간이 매우 짧게 발생하는 방식이다.

기존 Serial GC에서는 모든 애플리케이션 스레드를 정지 후 GC를 시작하는데, 이 과정은 다음과 같이 2단계로 세분화 할 수 있다.

  1. 참조 여부 확인
  2. 사용하지 않는 객체 청소

CMS GC는 위와 같이 하나의 기능 안에서 이루어지던 2가지 작업을 세분화함과 동시에 별도의 스레드로 관련 작업을 수행한다.

먼저 initial mark 단계에서 생존한 객체만 탐색한 후 stop the world를 종료한다. 그리고 Concurrent Mark 단계에서 해당 객체들을 별도로 추적하여 참조가 되고 있는지 확인한다. 이 작업은 애플리케이션 스레드와 동시에 진행된다.

Remark 단계에서는 Concurrent Mark 단계에서 새로 할당된 객체나 참조가 끊긴 객체가 존재하는지 확인한다. 마지막으로 Concurrent Sweep 단계에서 GC 대상으로 선정된 객체들을 정리한다. 이 작업 또한 다른 스레드들과 동시에 진행된다.

애플리케이션의 빠른 응답 속도가 중요할 때 사용된다.

하지만 동시에 다수의 프로세스가 진행되기 때문에 다른 GC 방식보다 메모리와 CPU를 더 많이 사용하며, Compaction 단계가 기본적으로 수행되지 않아서 메모리 파편화가 많이 발생할 수 있다.

만약 Compaction 작업을 수행한다면 다른 GC 방식들에 비해 오히려 stop the world 시간이 길어져 기존의 장점이 상쇄되기 때문에 사용에 신중을 기해야 한다.

G1 GC

다운로드

  • Humonogous: 용량이 큰 객체를 저장하기 위한 공간
  • Available/Unused: 아직 사용되지 않은 공간

G1 GC는 기존의 GC들과는 전혀 다른 접근법을 가진다.

young, old의 구역이 명확했던 이전 GC들과 달리 G1 GC는 전체 힙 메모리 영역을 특정한 역할로 나누며, 배정되는 크기와 역할은 동적으로 변경된다.

다운로드 (1)

먼저 Old Region(=한개의 칸)에 존재하는 객체들이 참조하는 Survivor Region을 탐색 후, 해당 객체들을 스캔한다.

GC에서 제외할 객체를 선별 후, 살아있는 객체가 가장 적은 Region을 청소한다. 그 후 해당 블록에서 생존한 객체들은 새로운 Region(Available/Unused)으로 복사, 정렬하여 파편화를 방지한다.

그동안 언급한 GC들에 비해 훨씬 빠른 퍼포먼스를 보인다고 하며, 이러한 바둑판식 발상은 다음에 나올 GC에서도 사용된다.

Z GC

다운로드 (2)

Stop The World 시간을 최대한 작게(10ms 이하)하는 것을 목표로 개발된 GC이다.

힙의 모든 살아있는 객체를 식별하고 추적하는 Marking 단계, 객체들을 재배치하는 Relocation 단계, 재배치된 객체들의 참조를 새로 업데이트 하는 Remapping 단계, 제거된 객체를 모두 회수하는 Reclaim까지 크게 4단계의 동작으로 구분된다.

다운로드 (3)

다음과 같은 64비트 포인터를 이용한다고 하며,

finalizer을 통해서만 참조되는 Finalizable 부분, 재배치 여부를 판단하는 Remapped, 오브젝트의 생존 여부 판별에 사용되는 Marked 1 / 0이 존재한다고 한다.

글들을 많이 읽어봤는데 ZGC는 단시간에 이해하기에는 역부족인 것 같다. 차후 다시 정리해야겠다.

참고

  • jaehoney, JVM - GC 알고리즘 알아보기! (feat. JDK 버전 별 Default), https://jaehoney.tistory.com/301
  • naver d2, Java Garbage Collection, https://d2.naver.com/helloworld/1329
  • huisam, JVM과 Garbage Collection - G1GC vs ZGC, https://huisam.tistory.com/entry/jvmgc
  • naver d2, ZGC의 기본 개념 이해하기, https://d2.naver.com/helloworld/0128759?ref=codenary
  • choiseokwon, Java: Z Garbage Collection (ZGC), https://choiseokwon.tistory.com/373
  • 드림어스컴퍼니 블로그, ZGC에 대해서, https://www.blog-dreamus.com/post/zgc%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C
This post is licensed under CC BY 4.0 by the author.

© . Some rights reserved.

Using the Jekyll theme Chirpy