다양한 GC 알고리즘(Serial, Parallel, CMS)의 특징과 장단점 비교

지난 포스팅에서는 가비지 컬렉션(GC)의 기본 원리와, 시스템을 멈추게 하는 ‘Stop-The-World(STW)’ 현상에 대해 알아보았습니다. GC가 메모리를 청소하는 동안 애플리케이션이 멈추는 것은 불가피하지만, ‘얼마나 오래 멈출 것인가’는 어떤 GC 알고리즘을 선택하느냐에 따라 크게 달라집니다.

Java는 애플리케이션의 규모와 서버의 하드웨어 환경(CPU 코어 수 등)에 맞춰 최적의 성능을 낼 수 있도록 다양한 GC 알고리즘을 제공해 왔습니다. 이번 글에서는 Java의 역사와 함께 발전해 온 대표적인 3가지 초중기 GC 알고리즘인 Serial GC, Parallel GC, CMS GC의 작동 방식과 장단점을 비교해 보겠습니다.

1. Serial GC (시리얼 GC): 단순함의 미학

Serial GC는 이름 그대로 단 하나의 스레드(Single Thread)만을 사용하여 가비지 컬렉션을 수행하는 가장 오래되고 단순한 방식입니다.

  • 작동 방식: Minor GC와 Major GC 모두 단일 스레드로 동작합니다. 청소를 혼자서 하다 보니 Stop-The-World 시간이 매우 길게 발생합니다.
  • 장점: 스레드 간의 동기화나 컨텍스트 스위칭(Context Switching) 오버헤드가 없기 때문에, CPU 코어가 1개인 매우 제한적인 환경에서는 오히려 가장 가볍고 효율적입니다.
  • 단점: 멀티 코어 환경의 이점을 전혀 살리지 못합니다. 메모리 용량이 크고 트래픽이 많은 웹 서버에 적용하면 최악의 성능 저하를 맛볼 수 있습니다.
  • 사용처: 메모리가 수십 MB 단위로 매우 적고 CPU 코어가 1개인 임베디드 기기나 데스크톱 애플리케이션에 적합합니다. (실무 엔터프라이즈 환경에서는 절대 사용하지 않습니다.)

2. Parallel GC (패러럴 GC): 처리량(Throughput) 극대화

Parallel GC는 Serial GC의 단점을 극복하기 위해 등장했으며, Java 8의 디폴트(기본) GC로 널리 사용된 알고리즘입니다. ‘Throughput GC’라고도 불립니다.

  • 작동 방식: 가비지 컬렉션을 수행할 때 여러 개의 스레드를 동시(Parallel)에 사용합니다. 메모리를 청소하는 인력이 한 명에서 여러 명으로 늘어난 것과 같습니다.
  • 장점: 멀티 코어 CPU의 성능을 적극적으로 활용하여 Stop-The-World 시간을 Serial GC 대비 획기적으로 단축시킵니다. 애플리케이션 전체의 처리량(Throughput)을 높이는 데 최적화되어 있습니다.
  • 단점: 청소 속도가 빨라졌을 뿐, 여전히 청소를 시작하면 애플리케이션 스레드는 멈춰야 합니다(STW 발생). 응답 시간이 0.1초 단위로 중요한 서비스에서는 한계가 있습니다.
  • 사용처: 백그라운드에서 대량의 데이터를 한 번에 처리하는 배치(Batch) 작업이나, 야간에 집계되는 통계 리포트 생성 서버 등 ‘응답 속도’보다 ‘전체 데이터 처리량’이 중요한 시스템에 적합합니다.

3. CMS GC (Concurrent Mark Sweep): 저지연(Low Latency)의 시작

처리량보다 ‘응답 속도(짧은 대기 시간)’가 훨씬 중요한 대규모 웹 애플리케이션을 위해 탄생한 것이 바로 CMS GC입니다.

  • 작동 방식: Stop-The-World 시간을 최소화하기 위해, 애플리케이션 스레드와 GC 스레드가 동시에(Concurrent) 실행되도록 설계되었습니다. 살아있는 객체를 찾는 Mark 작업을 여러 단계(Initial Mark -> Concurrent Mark -> Remark)로 쪼개어, 애플리케이션이 멈추는 시간을 극단적으로 줄였습니다.
  • 장점: Stop-The-World 시간이 매우 짧아, 사용자에게 지연 없는 쾌적한 응답 속도를 제공합니다.
  • 단점: 알고리즘이 매우 복잡하여 CPU 자원을 평소에도 많이 소모합니다. 가장 치명적인 단점은 메모리 파편화(Fragmentation)를 해결하는 압축(Compaction) 작업을 기본적으로 수행하지 않는다는 것입니다. 파편화가 누적되어 더 이상 메모리를 할당할 수 없게 되면, 결국 Serial GC 방식으로 전환되어 엄청나게 긴 Stop-The-World가 발생합니다.
  • 현재 위상: 치명적인 메모리 단편화 문제와 높은 유지보수 난이도로 인해 Java 9부터 Deprecated(사용 권장 안 함) 처리되었고, Java 14에서는 완전히 삭제되었습니다.

결론: 환경에 맞는 GC 선택의 중요성

Serial GC가 1차선 도로라면, Parallel GC는 다차선 도로를 뚫어 처리량을 높였고, CMS GC는 신호등 대기 시간을 줄여 응답 속도를 높이려 했던 기술적 진보의 과정입니다. 실무에서는 서버의 코어 수, 애플리케이션의 특성(배치 vs 실시간 웹), 메모리 크기를 종합적으로 고려하여 JVM 옵션을 통해 명시적으로 GC 알고리즘을 지정해 주어야 합니다.

그렇다면 CMS GC가 삭제된 현대의 Java 서버들은 어떤 알고리즘을 사용하고 있을까요? 다음 포스팅에서는 대규모 트래픽 시스템의 표준으로 자리 잡은 ‘G1 GC의 구조적 특징과 대규모 트래픽 시스템에서의 튜닝 포인트’를 깊이 있게 분석해 보겠습니다.

댓글 남기기