CRuby GC 성능 개선: 지연 스윕(Lazy Sweep) 구현 및 미래 방향

[27M06] We can make the GC X times slower than the original (ja)

작성자
RubyKaigi
발행일
2025년 10월 05일

핵심 요약

  • 1 CRuby GC에 지연 스윕(Lazy Sweep) 알고리즘을 구현하여 GC의 최대 정지 시간을 약 42% 개선하였으며, 이는 Ruby 1.9.3부터 사용 가능할 예정입니다.
  • 2 기존 Mark & Sweep GC의 'Stop The World' 문제 해결을 위해 스윕 작업을 객체 할당 시점으로 지연시켜 GC 부하를 분산하고 애플리케이션의 반응성을 높였습니다.
  • 3 보수적 GC의 장점을 유지하면서도 성능을 최적화하고, 향후 병렬 마킹, 특수 힙 도입 및 라이트 배리어와 같은 비정지형 GC로의 이행을 목표로 CRuby GC의 지속적인 발전을 모색하고 있습니다.

도입

본 발표는 CRuby 커미터인 나루이(成井) 씨가 Ruby의 가비지 컬렉터(GC) 성능 개선을 위해 구현한 '지연 스윕(Lazy Sweep)' 알고리즘에 대해 다룹니다. 기존 CRuby GC는 'Stop The World'라는 문제로 인해 애플리케이션의 실행이 일시적으로 멈추는 현상이 발생했으며, 이는 특히 실시간성이 중요한 애플리케이션에서 치명적인 단점으로 작용했습니다. 발표자는 이러한 문제를 해결하고 사용자 경험을 향상시키기 위한 지연 스윕의 도입 배경과 그 효과를 설명합니다.

CRuby GC의 개요 및 문제점

CRuby의 GC는 Mark & Sweep 알고리즘과 보수적 GC(Conservative GC)를 채택하고 있습니다. Ruby 객체는 RVALUE 구조체로 표현되며, 이 구조체 내의 flags에는 마크 비트와 타입 정보가 포함됩니다. GC는 루트(프로그램에서 직접 참조하는 객체)로부터 시작하여 살아있는 객체에 마크를 하고, 마크되지 않은 객체를 쓰레기로 간주하여 제거하는 방식으로 동작합니다.

그러나 기존 CRuby GC의 가장 큰 문제점은 ‘Stop The World’ 현상입니다. GC가 실행되는 동안 애플리케이션의 모든 동작이 멈추게 되는데, 객체 수가 증가할수록 최대 정지 시간도 비례하여 길어지는 알고리즘적 한계가 있었습니다. 이는 게임이나 로봇 제어와 같이 정지 시간이 중요한 애플리케이션에서 심각한 성능 저하를 유발했습니다.

지연 스윕(Lazy Sweep)의 도입

이러한 문제를 해결하기 위해 도입된 것이 ‘지연 스윕’입니다. 지연 스윕은 마크 단계가 완료된 후 스윕 작업을 즉시 수행하는 대신, 실제 객체 할당 요청이 발생할 때까지 스윕을 지연시키는 기술입니다. 이를 통해 스윕에 소요되는 부하를 객체 할당 시점으로 분산시켜 GC로 인한 최대 정지 시간을 줄이는 효과를 가져옵니다.

주요 구현 특징:

  • 스윕 지연: 마크 완료 후 GC는 정지하며, 사용자 요청 시에만 블록 단위로 스윕을 수행하여 객체를 반환합니다.

  • 힙 확장 타이밍 개선: 이전에는 스윕 시 미사용 객체 수를 세어 힙 확장 여부를 결정했으나, 지연 스윕에서는 마크 시점에 마크된 객체 수를 세어 사용 중인 객체 수를 파악하고, 이를 기반으로 힙 확장 및 스윕을 동시에 수행하여 부하를 분산합니다.

  • 힙 구조 변경: 보수적 GC의 포인터 식별을 위한 힙 슬롯 정렬 문제를 해결하기 위해, 정렬된 힙 슬롯 배열이 실제 힙 블록을 가리키는 구조로 변경하여 지연 스윕의 관리를 용이하게 했습니다.

  • 개발자 주의사항: 지연 스윕 환경에서는 마크가 객체에 계속 남아있으므로, 개발자가 임의로 마크를 제거할 경우 살아있는 객체가 해제되는 치명적인 버그를 유발할 수 있습니다.

성능 평가 및 데모

성능 평가 결과, 지연 스윕 도입 후 GC의 최대 정지 시간은 약 42% 개선되었습니다. 비록 전체 GC 소요 시간은 약 10% 증가했지만, 애플리케이션의 반응성을 저해하는 ‘최대 정지 시간’ 감소는 사용자 경험에 큰 영향을 미칩니다. ‘Kaboom’이라는 데모 애플리케이션을 통해 지연 스윕이 적용된 버전이 기존 버전보다 더 부드럽게 동작함을 시각적으로 확인할 수 있었습니다.

지연 스윕은 이미 CRuby 트렁크에 커밋되었으며, Ruby 1.9.3 버전에서 정식으로 사용 가능할 것으로 예상됩니다.

결론

나루이 씨의 지연 스윕 구현은 CRuby GC의 'Stop The World' 문제에 대한 중요한 진전을 보여주었습니다. 최대 정지 시간의 현저한 감소는 특히 고성능 및 실시간 반응성이 요구되는 Ruby 애플리케이션에 긍정적인 영향을 미칠 것입니다. 발표자는 앞으로도 보수적 GC의 잠재력을 최대한 활용하고, 스마트 객체 할당, 마크 단계 병렬화, 특정 타입 전용 힙 도입, 그리고 궁극적으로 라이트 배리어를 통한 비정지형 GC로의 전환 등 CRuby GC의 지속적인 발전을 위한 다양한 연구와 구현 과제를 제시했습니다. 이러한 노력은 Ruby 생태계 전체의 생산성과 안정성을 한층 더 높이는 데 기여할 것입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!