본문 바로가기
프로그래밍 언어/JAVA

GC(Garbage Collector) 란?

by 검은도자기 2021. 6. 19.

개요

시스템 엔지니어 일을 할 당시 자주 이슈가 되었던 GC에 대해서 공부한 후 정리하겠습니다.

 

 

GC(Garbage Collector)란?

JVM의 Heap 영역에서 사용하지 않는 객체를 제거하여 메모리 공간을 확보하는 데몬 스레드를 말합니다.

* 가비지: 사용하지 않는 객체

 

 

GC의 종류

 

Serial GC

- 싱글 스레드로 GC를 처리함

- 다른 GC에 비해 Stop-the-world 시간이 김

- JVM 옵션 -XX:+UseSerialGC

- 순차적인 GC

- Mark-Compact(Sweep 포함) 알고리즘 사용

 

Parallel GC

- Java 8의 defailt GC

- Young 영역의 GC를 멀티 스레드로 수행

- Serial GC에 비해 stop-the-world 시간 감소

 

Parallel Old GC

- Parallel GC를 개선

- Old 영역에서도 멀티 스레드 방식의 GC 수행

- Mark-Summary-Compact 알고리즘 사용

   sweep: 단일 쓰레드가 old 영역 전체를 체크

   summary: 멀티 쓰레드가 old 영역을 분리해서 체크

 

CMS GC (Concurrent Mark Sweep)

- stop-the-world 시간을 줄이기 위해 만들어짐

- compact 과정이 없음

- 메모리 단편화가 단점

 

G1 GC(Garbage First)

- CMS GC를 개선

- Java 9+의 default GC

- Heap을 일정한 크기의 Region으로 나눔

- 전체 Heap이 아닌 Region 단위로 탐색

- compact 진행

 

 

GC 수거 대상

1. 객체 값이 null인 경우

2. 블럭 코드 실행 종료 후, 블록 안에서 생성된 객체

3. 부모 객체가 null인 경우, 포함하는 자식 객체들이 대상

 

 

JVM Heap구조

 

JVM의 Heap영역은 처음 설계될 때 다음의 2가지를 전제 조건(Weak Generational Hypothesis)으로 설계되었다.

1. 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.

2. 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

 

즉, 객체는 대부분 일회성 되며, 메모리에 오랫동안 남아있는 경우는 드물다는 것이다. 그렇기 때문에 객체의 생존 기간에 따라 물리적인 Heap 영역을 나누게 되었는데, 이에 따라 크게 Young, Old 총 2가지 영역으로 설계되었다.

 

Young 영역(Young Generation)

  • 새롭게 생성된 객체가 할당(Allocation)되는 영역
  • 대부분의 객체가 금방 Unreachable 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라짐.
  • Young 영역에 대한 가비지 컬렉션(Garbage Collection)을 Minor GC라고 부른다.
  • Young 영역은 다시 Eden 영역과 두 개의 Survivor 영역으로 나뉜다.

 

Old 영역(Old Generation)

  • 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사되는 영역
  • 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다.
  • 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 말한다.

 

 

GC 동작 방식

  1. 운영 체제에서 메모리를 할당하고 다시 제공합니다.
  2. 요청 시 해당 메모리를 애플리케이션에 전달합니다.
  3. 해당 메모리의 어느 부분이 응용 프로그램에서 여전히 사용 중인지 확인합니다.
  4. 애플리케이션에서 재사용할 수 있도록 사용되지 않은 메모리를 회수합니다.

 

Young 영역과 Old 영역은 서로 다른 메모리 구조로 되어 있기 때문에, 세부적인 동작 방식은 다르다. 하지만 기본적으로 가비지 컬렉션이 실행된다고 하면 다음의 2가지 공통적인 단계를 따르게 된다.

 

1. Stop The World

가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다.

stop-the-world가 발생하면 GC를 실행하는 스레드를 제외한 모든 스레드들의 작업이 중단되고, GC가 완료되면 중단했던 작업을 다시 시작한다.

어떤 GC 알고리즘을 사용하더라도 stop-the-world는 발생한다. 대개의 경우 GC 튜닝이란 이 stop-the-world 시간을 줄이는 것이다.

 

2. Mark and Sweep

  • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
  • Sweep: Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업

 

Stop The World를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각이 어떤 객체를 참고하고 있는지를 탐색하게 된다. 그리고 사용되고 있는 메모리를 식별하는데, 이러한 과정을 Mark라고 한다. 이후에 Mark가 되지 않은 객체들을 메모리에서 제거하는데, 이러한 과정을 Sweep라고 한다.

 

 

GC 영역별 처리 절차

1. 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.

2. Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.

3. Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 객체가 계속 쌓인다.

4. 하나의 Survivor 영역이 가득 차게 되면 그중에서 살아남은 객체를 다른 Survivor 영역으로 이동한다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태로 된다.

5. 이 과정을 반복하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동하게 된다.

 

 

GC 장점

  • 사용되지 않은 메모리 공간은 GC에서 자동으로 처리하므로 수동 메모리 할당 / 할당 해제 처리 없음
  • Dangling Pointer를 처리하는 오버 헤드 없음
  • 자동 메모리 누수 관리

 

 

GC 단점

  • 객체 참조 생성 / 삭제를 추적하려면 더 많은 CPU 성능이 필요하며 대용량 메모리가 필요한 요청의 성능에 영향을 미칠 수 있습니다.
  • 프로그래머는 더 이상 필요하지 않은 개체를 해제하는 데 할당된 CPU 시간 일정을 제어할 수 없습니다.
  • 일부 GC 구현을 사용하면 애플리케이션이 예기치 않게 중지 될 수 있습니다.
  • 어떤 경우에는 자동 메모리 관리가 적절한 수동 메모리 할당 / 할당 해제만큼 효율적이지 않을 수 있습니다.

 

 

마무리

내용들이 생각보다 복잡하고 어려웠던거 같습니다. 정리하고 있는 지금도 과연 제대로 공부해서 정리한 걸까?라는 의문이 들긴 하지만, 이전 실제 필드에서 고생한 기억을 떠올리면서 마무리를 한 거 같네요.

아직 부족하거나 틀린 부분이 있을 수도 있으니 주의하시면 좋을거 같습니다.

이번 포스팅은 마무리 하면서 다음 포스팅에서 뵙겠습니다.

 

 

참고)

https://www.oracle.com/java/technologies/javase/jdk11-readme.html

https://docs.oracle.com/en/java/javase/11/

https://docs.oracle.com/javase/specs/jls/se11/html/index.html

https://docs.oracle.com/javase/specs/jvms/se11/html/index.html

https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

https://docs.oracle.com/en/java/javase/11/gctuning/garbage-first-garbage-collector-tuning.html#GUID-0DD93225-0BCF-4605-B365-E9833F5BD2FC

https://www.oracle.com/java/technologies/javase-downloads.html

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

https://velog.io/@whwpfoo/JVM-GC-Garbage-Collection

https://johngrib.github.io/wiki/java-gc-tuning/

https://velog.io/@hygoogi/%EC% 9E%90% EB% B0%94-GC% EC%97%90-%EB% 8C%80% ED%95% B4% EC%84%9C

https://mangkyu.tistory.com/118

https://velog.io/@harrynam/Java-GC

https://velog.io/@dbswl31024/Garbage-Collection-GC

https://javatutorial.net/java-garbage-collection

https://www.youtube.com/watch?v=Fe3TVCEJhzo&t=137s 

https://www.youtube.com/watch?v=vZRmCbl871I 

https://beststar-1.tistory.com/16

https://www.nextree.co.kr/p3878/

https://ananya281294.medium.com/garbage-garbage-go-away-2b3ea0d4ed40