가비지 컬렉션 (GC) 알고리즘 종류

이동엽·2025년 9월 30일

Old 영역에서 GC를 수행하는데에 Stop-The-World가 발생되고, 이걸 최적화 하기 위해 다양한 가비지 컬렉션 알고리즘이 개발 됐습니다.

상황에 따라 필요한 GC 를 설정을 통해 java에 적용할수 있습니다.

Serial GC

  • 서버 CPU 코어가 1개 일때 사용하기 위해 개발된 단순한 GC

  • GC를 처리하는 쓰레드가 1개 여서 가장 Stop-the-world 시간이 길다.

  • 보통 실무에서 사용하는 경우는 없다 (디바이스 성능이 안좋아서 CPU 코어가 1개인 경우에만 사용) 

  • Minor GC 에는 Mark-Sweep를 사용하고, Major GC에는 Mark-Sweep-Compact를 사용한다.
    ->기존 작업에서 Compact라는 작업이 추가된것입니다.

    Compact 작업은 Heap 영역을 정리하기 위한 단계.
    우선 Old 영역의 살아있는 객첼르 식별(Mark) 하고ㅓ Sweep해 살아남는것만 남긴다.
    그리고 Heap 영역의 앞 부분부터 채워서 객체가 존재하는 부분과 존재 하지않는 부분으로 나눈다(Compact)

    실행 명령어는
    -XX:+UseSerialGC GC 옵션을 지정해 알고리즘을 설정한다.

java -XX:+UseSerialGC -jar Application.java

Parallel GC

  • Throughput GC라고도 부르며 Serial GC와 기본적인 처리 과정은 동일하다.
  • Younh 영역의 Minor GC를 멀티 쓰레드로 수행하고 Old 영역은 싱글 쓰레드로 수행한다.
  • Serial GC에 비해 Stop-the-World 시간이 감소
    -> 이 GC는 멀티 프로세서나 멀티 스레드 머신에서 큰 규모의 데이터를 처리하는 애플리케이션을 위해 만들어졌다.

명령어

java -XX:+UseParallerGC

 
//사용할 스레드 개수 설정
-XX:ParallelGCThreads=<N>

// 최대 지연 시간 설정
-XX:MaxGCPauseMillis=<N>
출처: https://seungh1024.tistory.com/73 [학습 정리:티스토리]

Parallel Old GC (Parallel Compacting Collector)

  • Parallel GC를 개선한 버전이다.
  • Young 영역 뿐만 아니라, Old 영역에서도 멀티 쓰레드로 GC 수행.
  • 새로운 가비지 컬렉션 청소 방식인 Mark-Summary-Compact 방식을 이용한다.

Summary 단계에서 앞서 GC를 수행한 영역에 대해 별도로 살아 있는 객체를 식별한다는 점에서 조금 다르고 약간 더 복잡하다.

명령어

java -XX:+UseConcMarkSweepGC

CMS GC (Concurrent Mark Sweep)

  • 애플리케이션 쓰레드와 GC 쓰레드가 동시에 실행되서 Stop-the-world 시간을 최대한 줄일려고 만든 GC 알고리즘이다.
  • 모든 애플리케이션의 응답 속도가 중요할 때 사용한다.
  • 이것도 마찬가지로 여러 쓰레드 사용

단점으론

다른 알고리즘 보다 CPU를 더 많이 사용하고 Compaction 단계를 수행하지 않는다.
그래서 오래 운영되면 조각난 메모리들이 많아 Compaction 단계가 수행 됐을때 stop-the-world 시간이 길어지는 문제가 발생하기 때문에
Compaction 작업을 얼마나 하는지, 오랫동안 수행하는지 확인해야한다.

그래서 GC는 Java9 버젼부터 deprecated 되었고 결국 Java14에서는 사용이 중지됐다.

명령어

java -XX:+UseConcMarkSweepGC -jar Application.java

G1 GC(Garbage First)

장기적으로 서비스 운영 할때 CMS GC에서 생기는 문제를 해결하기 위해 개발됐습니다.

  • Java 9버전 디폴트 GC
  • 기존 GC는 Old,Young 영역을 나눠서 사용했지만, 이건 Region이라는 개념을 사용합니다.
  • 전체 Heap 영역을 Region이라는 영역으로 체스 같이 분할해서 상황에 따라서 Eden,Survivor,Old 등 역할을 고정으로 하는게 아니라 동적으로 부여합니다.
  • Garbage로 가득찬 영역을 빠르게 회수하여 빈 공간을 확보하므로, 결국 GC 빈도가 줄어드는 효과를 얻게 되는 원리이다.

그림을 보면 Eden,Survivor,Old에 Available/Unused 와 Humonogous 라는 2가지 역할이 추가되었다. Available/Unused는 사용되지 않는 영역을 의미하며 Humonogous는 영역 크기의 50%를 초과하는 객체를 저장하는 영역을 의미합니다.

그래서 핵심은 Heap영역을 동일한 크기로 나누고 Garbage가 많은 영역을 우선적으로하여 GC를 수행하고, 객체들을 순차적으로 이동하지않고, 더 효율적으로 생각하는 위치로 재활당시킨다.
이것도 마찬가지로 Minor GC, Major GC로 나누어져서 수행된다.

java -XX:+UseG1GC -jar Application.java

Shenandoah GC

  • java 12버전 GC
  • 기존 CMS가 가진 단편화, G1의 pause의 이슈를 해결한 알고리즘.
  • 강력한 concurrency와 가벼운 GC 로직으로 heap 사이즈에 영향 받지않고 일정한 pause 시간이 소요가 특징이다.
java -XX:+UseShenandoahGC -jar Application.java

ZGC (Z Garbage Collector)

  • Java 15버전 GC
  • 대량 메모리(8MB - 16TB)를 low-latency로 잘처리하기 위한 GC
  • G1의 Region처럼 ZPage라는 영역을 사용합니다.
  • Region은 크기가 고정인데, ZPage는 2mb 배수로 동적이다.
    -> 큰 객체가 들어오면 2^로 영역을 구성해서 처리한다.

장점으론 힙 크기가 증가하더도 'stop-the-world'의 시간이 절대 10ms를 넘지 않는다는 것이다.

참고

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC#old_%EC%98%81%EC%97%ADold_generation

https://seungh1024.tistory.com/73

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

profile
씨앗

0개의 댓글