Link
Today
Total
12-12 07:23
Archives
관리 메뉴

초보개발자 긍.응.성

JVM 가비지 컬렉터의 종류 본문

책 정리

JVM 가비지 컬렉터의 종류

긍.응.성 2021. 7. 21. 22:31
반응형

현재 우리팀은 Java8을 사용중이다. 동료분이 JVM 버전을 11 업그레이드 하자는 제안이 있었고, 주요 변경 내용을 소개하는 중에 새로운 가비지 컬렉터를 지원한다는 내용이 있었다. Java11부터 experimental하게 ZGC를 사용가능하며 현재사용하는 G1GC보다 짧은 지연 시간을 갖도록 개선된 GC라고 들었다. GC에 대한 배경지식이 부족했던 터라 자료를 찾던 중 baeldung 아저씨의 블로그를 보게되었고, 이는 그 블로그의 내용의 정리한 글이다.

JVM Garbage Collectors

Garbage Collection(이하 GC)은 이름에서 알 수 있듯이 메모리의 garbage를 찾아 제거하는 역할을 한다. 실제 동작으로는 JVM 힙 메모리의 사용가능한 모든 Object를 트래킹하며 사용하지 않는 것들을 제거한다.

GC는 Mark와 Sweep이라는 두 가지 Step으로 이루어져 있다.

  • Mark는 사용하는 메모리 조각과 그렇지 않은(사용하지 않는) 메모리 조각을 식별하여 마킹하는 단계이며
  • Sweep는 mark 단계에서 식별하여 마킹된 객체들을 삭제하는 행위이다.

GC의 장단점

장점

  • 메모리 할당/해제 불필요
  • Dangling Pointer 오버헤드 없음 (아무것도 가리키지 않는 포인터)
  • 자동 Memory Leak 매니지먼트(완전한 매니지먼트는 아니다)

단점

  • JVM이 지속적으로 객체 ref를 트랙킹하다 보니, 기존 application 성능을 내기 위해서는 더 큰 CPU power가 요구된다. 그리고 메모리의 용량 크기가 성능을 좌우할 수 있다
  • 자원 해제를 위한 CPU타임을 커스터마이징하게 가져갈 수 없다
  • GC가 동작 할때 예측하지 못하게 application이 중지될 수 있다
  • 자동 메모리 관리가 적절한 메모리 할당과 해제를 충족시키지 않을 수 있다

GC의 종류

  • Serial Garbage Collector
  • Parallel Garbage Collector
  • CMS Garbage Collector
  • G1 Garbage Collector
  • Z Garbage Collector

Serial Garbage Collector

  • 가장 간단한 GC 구현체이며 싱글 스레드로 동작한다
  • GC가 실행될 때 모든 애플리케이션 스레드가 정지하게된다
  • 그렇기에 서버환경이나 멀티스레드 프로그램에서 이 GC는 좋지않은 방법이다
  • 잠시 일시중지 시간이 존재해도 관계가 없는 애플리케이션일 경우 선택하되는 GC 방식이다
  • Serial GC 활성화 옵션
java -XX:+UseSerialGC -jar Application.java

Parallel Garbage Collector

  • JVM의 default GC이며 Throughtput Collectors라 불린다
  • Serial GC와 달리 힙 공간 관리를 위해 다수의 스레드를 사용한다
  • GC가 수행될 때 다른 애플리케이션 스레드들이 정지하게 되는것은 동일하다
  • GC 수행 스레드 개수(maximum garbage collection threads), 일시중지 시간(pause time), 처리량(throughput) 및 힙 크기(heap size)를 지정할 수 있다
    • GC 스레드 개수는 커맨드 옵션 : -XX:ParallelGCThreads=<N>
    • 최대 일시중지 시간은 커맨드 옵션 : -XX:MaxGCPauseMillis=<N>
    • GC수행시간과 GC외 소요시간을 비율 : -XX:GCTimeRatio=<N>
      • (GC 외 소요시간 / GC 수행시간)
      • -XX:GCTimeRatio=19 - 5% GC, 95% 처리
    • (프로그램 동작에 필요한) 최대 힙크기 : -Xms<N>
  • Parallel GC 활성화 옵션
java -XX:+UseParallelGC -jar Application.java

CMS Garbage Collector

  • Concurrent Mark Sweep 방식은 다수의 GC스레드를 사용한다.
  • 이 방식은 GC 동작 시 최소한의 pause 타임을 가지도록 하게위해 설계되었다
  • 애플리케이션이 실행되는 동안 GC와 프로세서 리소스를 공유할 수 있다
  • CMS GC를 사용할 경우 애플리케이션의 평균 응답 시간은 조금 느려질 수 있지만 GC에 의해 애플리케이션이 정지되지 않는다
  • 주의할 점은 이 GC방식을 사용한다면 System.gc()와 같이 명시적으로 가비지 수집을 호출하면 동시모드가 실패하고 중단된다
  • 총 98%이상이 CMS 가비지 수집에 소비되고 힙의 2% 미만이 복구되면 CMS 수집기에서 OutOfMemoryError가 발생한다
    • 위 에러는 커맨드 옵션으로 비활성화 가능하다 -XX:-UseGCOverheatLimit
  • CMS의 개선 모드도 존재하며, 현재 Java SE 8와 이후엔 deprecated 되었다
  • CMS GC 활성화 옵션
    • Java 9 사용시 warning message
    • >> java -XX:+UseConcMarkSweepGC --version Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. java version "9.0.1"
    • Java 14
    • >> java -XX:+UseConcMarkSweepGC --version OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 openjdk 14 2020-03-17
  • java -XX:+UseParNewGC -jar Application.java

G1 Garbage Collector

  • 큰 메모리 공간을 가지고있는 멀티 프로세서용으로 디자인된 GC
  • CMS GC보다 좋은 성능을 보이며 G1으로 대체되었다

G1 GC의 동작 과정

Marking

다른 GC와 달리 G1은 힙을 동일한 크기인 영역(region)으로 분할한다. 각 영역은 가상 메모리에서 연속된 공간으로 위치한다. G1은 힙 전체에 대해 liveness를 결정하기 위해 동시에 모든 힙 영역에 marking을 수행한다

Sweeping

마킹 단계가 끝나면, G1은 가장 많이 비어있는 영역을 찾아내며, 해당 영역에 대해 먼저 GC를 수행한다. 이는 일반적으로 가장 많은 양의 free space를 생성한다. 이러한 동작 방식 때문에 G1GC는 Garbage-First GC라는 이름으로 불리기도 한다.

  • G1 GC 활성화 옵션
  • java -XX:+UseG1GC -jar Application.java

 

 

Java 8의 변화

Java 8u20는 같은 String 타입에 대하여 불필요한 중복 인스턴스를 생성하지 않도록 새로운 JVM 파라미터를 제공하였다. 이로써 중복된 String 값과 글로벌한 char[] 배열의 중복을 제거하는 최적화가 가능하다.

이 파라미터는 아래의 JVM 파라미터를 통해 활성화할 수 있다

-XX:+UseStringDuplication

Z Garbage Collector

ZGC는 Java11에서 Linux 환경에 대해 실험적으로 소개된 확장성이 있는 짧은 지연 시간을 갖는 GC이다. JDK 14는 ZGC를 Windows, macOS 운영체제에 대해서도 지원한다. ZGC는 Java15부터는 Production 상태로 제공된다.

ZGC는 애플리케이션 스레드의 실행을 10ms 이상 중단하지 않으며 고가의 모든 작업을 동시에 수행하므로 짧은 지연 시간이 필요한 애플리케이션에 적합하다. 또한 색상이 지정된 포인터와 로드 장벽(load barriers with colored pointers)을 사용하여 스레드가 실행 중일 때 동시 작업을 수행하고 힙 사용량을 추적하는 데 사용된다.

coloring pointer는 ZGC의 코어한 개념이다 이다. ZGC는 reference의 일부 bit를 사용하여 개체의 상태를 표시한다. 이는 8MB~16TB 범위의 힙영역에 대해 가능하며 힙, 루트 세트 크기에 따라 일시 중지 시간이 증가하지 않는다

G1과 비슷하게 ZGC도 힙 영역을 파티션하지만, 동일한 사이즈로 분할하지는 않는다는것이 차이점이다.

  • ZGC 활성화 옵션 (JDK 15미만)
  • java -XX:+UnlockExperimentalVMOption -XX:+UseZGC -jar Application.java
  • ZGC 활성화 옵션 (JDK 15이상)
  • java -XX:+UseZGC -jar Application.java
반응형
Comments