본문 바로가기
JAVA

[JAVA] Garbage Collection(가비지 컬렉션) 알고리즘 종류

by yonikim 2023. 12. 22.
728x90

 

JVM 이 메모리를 자동으로 관리해주는 것은 개발자의 입장에서 상당한 메리트이다. 

 

하지만 문제는 GC 를 수행하기 위해 Stop The World 가 발생되고, 이 때문에 애플리케이션이 중지된느 문제점이 발생하게 되었다.

또한 자바가 발전됨에 따라 Heap의 사이즈가 커지면서 애플리케이션의 지연(Suspend) 현상이 두드러지게 되었고, 이를 최적화하기 위해 다양한 Garbae Collection(가비지 컬렉션) 알고리즘이 개발되었다. 

 

 

Serial GC 


  • 서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 가장 단순한 GC
  • GC 를 처리하는 쓰레드가 1개(싱글 쓰레드)여 이기 때문에 stop-the-world 시간이 가장 길다. 
  • Minor GC 에는 Mark-Sweep 을 사용하고, Major GC 에는 Mark-Sweep-Compact 를 사용한다.
  • 보통 실무에서 사용하는 경우는 없다. (디바이스 성능이 안좋아서 CPU 코어가 1개인 경우에만 사용)

 

※ Serial GC 실행 명령어 

자바 프로그램을 실행할때 -XX:+UseSerialGC 옵션을 지정하여 해당 가비지 컬렉션 알고리즘으로 힙 메모리를 관리하도록 실행할 수 있다. 

java -XX:+UseSerialGC -jar Application.java

 

 

Paraller GC 


  • Java 8 의 디폴트 GC 
  • Serial GC 와 기본적인 알고리즘은 같지만, Young 영역의 Minor GC 를 멀티 쓰레드로 수행 (Old 영역은 여전히 싱글 쓰레드)
  • Serial GC 에 비해 stop-the-world 시간 감소

 

※ Paraller GC 실행 명령어 

GC 스레드는 기본적으로 CPU 개수만큼 할당된다. 옵션을 통해 사용할 쓰레드의 개수 등을 설정해줄 수 있다.

java -XX:+UseParallelGC -jar Application.java 
# -XX:ParallelGCThreads=N : 사용할 쓰레드의 개수

 

 

Paraller Old GC (Paraller Compacting Collector)


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

 

※ Paraller Old GC 실행 명령어 

java -XX:+UseParallelOldGC -jar Application.java
# -XX:ParallelGCThreads=N : 사용할 쓰레드의 개수

 

 

CMS GC (Concurrent Mark Sweep)


  • 어플리케이션의 쓰레드와 GC 쓰레드가 동시에 실행되어 stop-the-world 시간을 최대한 줄이기 위해 고안된 GC
  • 단, GC 과정이 매우 복잡해짐
  • GC 대상을 파악하는 과정이 복잡한 여러단계로 수행되기 때문에 다른 GC 대비 CPU 사용량이 높다.
  • 메모리 파편화 문제
  • CMS GC 는 Java 9 버전부터 deprecated 되었고, 결국 Java 14 버전에서는 사용 중지

 

※ CMS GC 실행 명령어 

# deprecated in java9 and finally dropped in java14
java -XX:+UseConcMarkSweepGC -jar Application.java

 

 

G1 GC (Garbage First)


  • CMS GC 를 대체하기 위해 jdk 7 버전에서 최초로 release 된 GC
  • JAVA 9+ 버전의 디폴트 GC 로 지정 
  • 4GB 이상의 힙 메모리, stop-the-world 시간이 0.5초 정도 필요한 상황에 사용 (Heap 이 너무 작을 경우 미사용 권장)
  • 기존의 GC 알고리즘에서는 Heap 영역을 물리적으로 고정된 Young / Old 영역으로 나누어 사용했지만, G1 GC 는 아예 이러한 개념을 뒤엎는 Region 이라는 개념을 새로 도입하여 사용 
  • 전체 Heap 영역을 Region 이라는 영역으로 체스같이 분할하여 상황에 따라 Eden, Survivor, Old 등 역할을 고정이 아닌 동적으로 부여
  • Garbage 로 가득찬 영역을 빠르게 회수하여 빈 공간을 확보하므로, 결국 GC 빈도가 줄어드는 효과를 얻게 되는 원리

※ G1 GC 의 효율성 
JAVA 9+ 부터 디폴트 GC 로 자리잡은 G1 GC 에서는 이전의 GC 들처럼 일일이 메모리를 탐색해 객체들을 제거하지 않는다. 
대신 메모리가 많이 차있는 영역(Region) 을 인식하는 기능을 통해 메모리가 많이 차있는 영역을 우선적으로 GC 한다.
즉, G1 GC 는 Heap Memory 전체를 탐색하는 것이 아닌, 영역(Region) 을 나눠 탐색하고 영역(Region) 별로 GC 가 일어난다.

또한 이전의 GC 들은 Young Generation 에 있는 객체들이 GC 가 돌때마다 살아남으면 Eden -> Survivor 0 -> Suvivor 1 으로 순차적으로 이동했지만, G1 GC 에서는 순차적으로 이동하지는 않는다.
대신 G1 GC 는 더욱 효율적이라고 생각하는 위치로 객체를 Rellocate(재할당) 시킨다.
예를 들어 Survivor 1 영역에 있는 객체가 Eden 영역으로 할당하는 것이 더 효율적이라고 판단될 경우 Eden 영역으로 이동시킨다.

 

 

※ CMS GC 실행 명령어 

java -XX:+UseG1GC -jar Application.java

 

 

 

Shenandoah GC


  • JAVA 12 버전에 release
  • 레드햇에서 개발한 GC
  •  기존 CMS GC 가 가진 단편화, G1 GC 가 가진 pause 의 이슈를 해결 
  • 강력한 Concurrency 와 가벼운 GC 로직으로 Heap 사이즈에 영향을 받지 않고 일정한 pause 시간 소요가 특징

 

※ Shenandoah GC 실행 명령어 

java -XX:+UseShenandoahGC -jar Application.java

 

 

 

ZGC (Z Garbage Collector)


  • JAVA 15 버전에 release 
  • 대량의 메모리(8MB~16TB) 를 low-latency 로 잘 처리하기 위해 디자인된 GC
  • G1 GC 의 Region 처럼, ZGC 는 ZPage 라는 영역을 사용하며, G1 GC 의 Region 은 크기가 고정인데 비해, ZPage 는 2mb 배수로 동적으로 운영됨 (큰 객체가 들어오면 2승 으로 영역을 구성해서 처리)
  • ZGC 가 내세우는 최대 장점 중 하나는 Heap 크기가 증가하더라도 stop-the-world 의 시간이 절대 10ms 를 넘지 않는다는 것

 

※ ZGC 실행 명령어 

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar Application.java

 

 

 

References 

가비지 컬렉션 동작 원리 & GC 종류

728x90

'JAVA' 카테고리의 다른 글

[JAVA] 리플렉션 (Reflection)  (1) 2023.12.22
[OOP] 객체지향 설계의 5가지 원칙 (SOLID)  (1) 2023.12.22
[JAVA] JVM 내부 구조 & 메모리 영역  (2) 2023.12.21