그래서 GC가 뭐죠?

Jaychy·2021년 4월 22일
0

기술 면접 질문

목록 보기
4/8
post-thumbnail

Hits

[모두가 기술 면접에 합격하는 그날까지]
https://github.com/Lee-Jin-Hyeok/technical-interview-question

개요

JVM에서는 Heap Area의 메모리 관리를 위해서 Garbage Collector(이하 GC)를 이용합니다.
이런 GC도 종류가 있으며, 각각 동작 방식이 다릅니다.
GC의 전체적인 동작 과정은 링크Runtime Data AreaHeap Area 항목을 보시면 될 것 같습니다.

GC는 메모리 관리를 위해 Garbage Collection 동작을 하는데
이 과정에서 Garbage Collection을 실행하는 스레드를 제외한 모든 스레드가 멈추는
Stop the world 현상이 일어나게 됩니다.

스레드가 멈춘다는 것은 곧 애플리케이션이 멈춘다는 뜻으로
서비스가 정상적으로 지속되는데 큰 영향을 줍니다.
그래서 Stop the world로 인한 멈춤 현상을 최소화하기 위하여 새로운 GC들이 개발되었습니다.

이런 Stop the world의 멈춤 현상 최소화 과정을 GC 튜닝 이라고 합니다.

본문

GC의 종류는 크게 다섯 가지로 나누어집니다.

1. Serial GC

초기 버전의 GCHeap AreaYoung Generation, Old Generation으로 나눠서
메모리를 관리하였습니다. 이 방법은 이후 세대에서도 계속 사용됩니다.

자세한 동작 과정은 위 링크를 통해 알 수 있습니다.

살아남을 객체를 표시(Mark)하고 쓰레기 객체를 정리(Sweep)하며,
단편화를 없애기 위해 압축(Compact)한다고 해서
Mark-Sweep-Compact 알고리즘이라고 합니다.

Serial GC는 초기 모델인 만큼 싱글 스레드로 Garbage Collection을 수행합니다.
따라서 작업 속도가 느리고 멀티 프로세싱이 되는 하드웨어의 성능을 이용할 수 없습니다.

2. Parallel GC

이름 그대로 Serial GC가 싱글 스레드로 동작한다는 문제점을 해결하기 위해
Garbage Collection을 멀티 스레드로 처리합니다.
단, Young Generation 영역에서 실행되는 Minor GC만 멀티 스레드로 처리하고
Old Generation 영역에서 실행되는 Major GC는 여전히 싱글 스레드로 처리합니다.

3. CMS (Concurrent Mark Sweep) GC

CMS GCGarbage Collection을 동작하는 동안 네 가지의 동작을 거칩니다.

  1. Initial Mark
    살아있는 객체를 찾아 마크만 합니다.
    이때 Stop the world 현상이 발생하지만
    모든 객체를 스캔하지 않고 살아있는 객체의 그래프를 탐색하기 때문에
    짧은 시간 멈추게 됩니다.
  2. Concurrent Mark
    (1)에서 찾은 객체들을 따라가며 모두 살아있는지 확인합니다.
    이때 애플리케이션을 멈추지 않으며 GC와 애플리케이션의 리소스를 공유합니다.
  3. Remark
    (2)에서 새로 생긴 객체나 참조가 끊긴 객체를 탐지합니다.
    이때는 Stop the world 현상이 발생합니다.
  4. Concurrent Sweep
    마크한 객체들을 Sweep하는 작업을 거칩니다.
    이때는 Stop the world 현상이 발생하지 않습니다.

이렇게 애플리케이션을 거의 멈추지 않고 Garbage Collection을 동작한다는 장점이 있지만,
GC와 애플리케이션이 동시에 작동하여 메모리와 CPU를 더 많이 잡아먹습니다.
또한 애플리케이션과 동시에 작동하는 바람에 Compact 작업을 거치지 않아,
큰 객체가 들어갈 공간을 확보하지 못할 수도 있습니다.

CMS 알고리즘을 적용하는 공간은 Old Generation 영역이며,
Young Generation 영역에서는 Parallel 알고리즘을 거의 그대로 사용합니다.

4. G1 GC

G1 GC는 이전 GC들 처럼 Young GenerationOld Generation 영역을 따로 구분짓지 않고
모두 1MB 크기의 리전(Region)으로 나눕니다.
들어가는 객체가 젊은 객체면 그 리전은 Young Generation으로 정해지고,
늙은 객체라면 그 리전은 Old Generation으로 정해집니다.

하나의 리전이 가득차면 살아있는 객체를 다른 Old 또는 Young 영역으로 옮기고
리전에 남은 객체들은 모두 삭제합니다.

이런식으로 크지 않은 공간의 객체를 계속 지움으로써 Stop the world 현상은
많이 발생할 수 있으나, 그만큼 멈추는 기간이 짧기 때문에 더 큰 효율을 볼 수 있습니다.
또한 리전 별로 객체를 제거하기 때문에 단편화의 문제도 해결할 수 있습니다.

5. ZGC

비교적 최근에 개발된 GCG1 GC 보다 빠르고 효율적인 Garbage Collection을 한다고 합니다.
정확한 것은 다음 링크에서 알아봐주세요.

참조

[CMS GC - Initial Mark]
https://stackoverflow.com/questions/50323753/java-cms-gc-initial-mark

profile
아름다운 코드를 꿈꾸는 백엔드 주니어 개발자입니다.

0개의 댓글