결론 및 연구 분야
우리는 가비지 컬렉션이 완전히 모듈화된 프로그래밍에 필수적이며, 유연하고 재사용 가능한 코드를 가능하게 하고 매우 위험한 코딩 오류의 큰 부분을 제거한다고 주장해왔다.
가비지 컬렉션 기술의 최근 발전으로 고성능 시스템에서 자동 메모리 회수를 경제적으로 사용할 수 있게 되었다. 비교적 단순한 가비지 컬렉터조차도 기존의 명시적 메모리 관리와 성능 면에서 경쟁력이 있는 경우가 많다. 세대별 기법은 객체가 젊은 나이에 소멸되는 경향이 있다는 경험적 관찰을 활용하여 컬렉션의 기본 비용과 방해 요소를 줄인다. 증분 기법은 심지어 하드 실시간 시스템에도 가비지 컬렉션을 상대적으로 매력적으로 만들 수 있다.
우리는 현재 연구 분야를 이해하기 위한 프레임워크를 제공하기 위해 여러 종류의 가비지 컬렉터의 기본 동작을 논의했다. 핵심 요점은 가비지 컬렉션 알고리즘에 대한 표준 교과서 분석이 일반적으로 컬렉터의 가장 중요한 특성, 즉 쓰기 장벽 오버헤드 및 지역성 효과와 같은 다양한 비용과 관련된 상수 계수를 놓치고 있다는 것이다. 마찬가지로 “실시간” 가비지 컬렉션은 널리 인식되는 것보다 더 미묘한 주제이다. 이러한 요소들로 인해 가비지 컬렉션 설계자는 세부적인 구현 문제를 고려하고 기능 선택에 매우 신중해야 한다. 실용적인 결정(예: 다른 언어의 기존 코드와 상호 운용해야 하는 필요성)이 성능의 작은 차이보다 더 중요할 수 있다.
이러한 복잡한 문제에도 불구하고, 많은 시스템은 실제로 가비지 컬렉터에 대해 상당히 단순한 요구 사항을 가지고 있으며, 몇 백 줄의 코드로 구성된 컬렉터를 사용할 수 있다. 크고 복잡한 최적화 컴파일러를 가진 시스템은 가비지 컬렉션에 더 많은 주의를 기울여야 하며 최신 기술을 사용해야 한다. (한 가지 유망한 발전은 이식 가능한 고수준 언어(일반적으로 C)로 작성되고 다양한 언어의 다양한 구현에 적용 가능한 가비지 컬렉터의 가용성이다.)
가비지 컬렉터 설계자는 또한 시스템 설계의 다른 측면의 발전을 따라잡아야 한다. 이 조사에서 설명된 기법은 대부분의 상대적으로 기존의 단일 프로세서 시스템에서 좋은 성능을 제공하기에 충분해 보이지만, 다른 영역의 지속적인 발전은 가비지 컬렉터 설계에 새로운 문제를 야기한다.
영속 객체 저장소는 대규모 상호 관련 데이터 구조를 파일에 쓰고 다시 필요할 때 다시 읽지 않고도 무기한 저장할 수 있게 한다. 포인터로 연결된 데이터 구조를 자동으로 보존함으로써 프로그래머를 지루하고 오류가 발생하기 쉬운 입출력 루틴 코딩에서 해방시킨다. 대규모 영속 객체 저장소는 많은 목적을 위해 파일 시스템을 대체할 수 있지만, 이는 대량의 장수명 데이터를 관리하는 문제를 야기한다. 영속 저장소가 가비지 컬렉션을 갖추는 것이 매우 바람직한데, 그래야 메모리 누수로 인해 회수되지 않은 메모리가 크고 영구적으로 축적되지 않기 때문이다. 대규모 영속 저장소의 가비지 컬렉션은 제한된 기간의 단일 프로세스 메모리를 가비지 컬렉션하는 것과는 매우 다른 작업이다. 사실상, 기존 시스템의 컬렉터는 파일에 기록된 데이터가 컬렉터의 관점에서 “사라지기” 때문에 매우 장수명 데이터의 문제를 피할 수 있다. 영속 저장소는 그러한 데이터를 가비지 컬렉션 범위 내에 유지하여 장수명 데이터의 자동 관리라는 매력적인 전망과 이를 효율적으로 수행하는 과제를 제공한다.
병렬 컴퓨터도 가비지 컬렉터에 새로운 문제를 제기한다. 컬렉터를 동시적으로 만드는 것, 즉 애플리케이션에서 사용하지 않는 프로세서를 활용하기 위해 애플리케이션과 별도의 프로세서에서 실행할 수 있게 하는 것이 바람직하다. 또한 컬렉터가 애플리케이션을 따라잡을 수 있도록 속도를 높일 수 있도록 컬렉터 자체를 병렬화하는 것도 바람직하다. 동시 컬렉터는 단순한 증분 컬렉션이 제기하는 것보다 다소 더 어려운 컬렉터와 뮤테이터 간의 조정 문제를 제기한다. 병렬 컬렉터는 또한 가비지 컬렉션 프로세스의 다양한 부분을 조정하고 순회되는 데이터 구조의 토폴로지로 인한 잠재적 병목 현상에도 불구하고 충분한 병렬성을 찾는 문제를 제기한다.
분산 시스템은 더 많은 문제를 야기한다. 컬렉션 프로세스가 여러 네트워크 컴퓨터에 걸쳐 진행되어야 하고 통신 비용이 높을 때 병렬성의 제한이 특히 심각하다. 장기 실행 애플리케이션이 있는 대규모 시스템에서 네트워크는 일반적으로 신뢰할 수 없으며, 이러한 시스템을 위한 분산 가비지 컬렉션 전략은 그 위에서 실행되는 애플리케이션과 마찬가지로 컴퓨터 및 네트워크 장애를 견딜 수 있을 만큼 견고해야 한다.
대규모 영속 또는 분산 시스템에서는 데이터 무결성이 특히 중요하다. 가비지 컬렉션 전략은 효율성과 컬렉터 자체가 실패하지 않도록 보장하기 위해 체크포인팅 및 복구와 조정되어야 한다.
고성능 그래픽 및 사운드 기능이 더 널리 이용 가능하고 경제적이 되면서 컴퓨터는 더 그래픽적이고 대화형 방식으로 사용될 가능성이 높다. 멀티미디어 및 가상 현실 애플리케이션은 큰 지연을 가하지 않는 가비지 컬렉션 기법을 필요로 하여 증분 기법을 점점 더 바람직하게 만든다. 임베디드 마이크로프로세서의 사용 증가는 하드 실시간 애플리케이션 프로그래밍을 용이하게 하는 것을 바람직하게 만들어 세밀한 증분 기법을 특히 매력적으로 만든다.
컴퓨터 시스템이 더욱 보편화되고 네트워크화되며 이질적이 되면서, 다른 컴퓨터에서 실행되고 극도로 다른 프로그래밍 언어로 개발되었을 수 있는 모듈을 통합하는 것이 점점 더 바람직해진다. 다양한 시스템 간의 상호 운용성은 미래의 중요한 목표이며, 이러한 시스템을 위한 가비지 컬렉션 전략을 개발해야 한다.
가비지 컬렉션은 많은 현재의 범용 및 전문 프로그래밍 시스템에 적용할 수 있지만, 새롭고 더욱 발전된 패러다임에 적응시키는 데는 상당한 작업이 남아 있다.
해결된 주요 문제들
이 논문에서 언급된 과제 중 현대에 와서 상당한 진전을 이룬 문제들을 소개합니다:
1. 저지연 실시간 가비지 컬렉션
논문에서의 우려: 멀티미디어와 가상 현실 애플리케이션을 위해 큰 지연 없는 GC가 필요하다고 언급했습니다.
현대의 해결책:
- ZGC (Z Garbage Collector): Java 11에 도입된 ZGC는 10ms 미만의 일시 정지 시간을 보장하며, 멀티 테라바이트 힙에서도 일시 정지 시간이 힙 크기와 무관합니다.
- Shenandoah GC: Red Hat이 개발한 저지연 GC로, 동시 컴팩션을 통해 일시 정지 시간을 크게 줄였습니다.
- 이러한 발전으로 게임, 금융 거래 시스템, 실시간 애플리케이션에서 GC를 사용하는 것이 실용적이 되었습니다.
2. 병렬 및 동시 가비지 컬렉션
논문에서의 우려: 병렬 컴퓨터에서 컬렉터를 효율적으로 병렬화하고 애플리케이션과 동시에 실행하는 것의 어려움을 언급했습니다.
현대의 해결책:
- G1 GC (Garbage First): Java 7에 도입되어 멀티코어 프로세서를 효과적으로 활용하는 병렬 및 동시 컬렉터입니다.
- Go 언어의 동시 GC: Go 1.5 이후 완전한 동시 GC를 구현하여 마이크로초 단위의 일시 정지 시간을 달성했습니다.
- 현대의 멀티코어 CPU 아키텍처와 함께 발전하여 병렬 GC는 이제 표준이 되었으며, 애플리케이션 성능에 미치는 영향을 최소화합니다.
3. 이기종 시스템 간 상호운용성
논문에서의 우려: 다른 언어로 개발된 모듈 간 통합과 상호운용성을 위한 GC 전략 개발이 필요하다고 언급했습니다.
현대의 해결책:
- WebAssembly (Wasm): 다양한 언어로 작성된 코드를 브라우저와 서버에서 실행할 수 있게 하며, GC 통합 표준을 개발 중입니다.
- GraalVM: 여러 언어(Java, JavaScript, Python, Ruby 등)를 단일 VM에서 실행하고 언어 간 상호운용을 지원하며 통합된 GC를 제공합니다.
- Foreign Function Interface (FFI) 발전: Rust의 안전한 FFI, Java의 Project Panama 등으로 메모리 관리가 다른 언어 간의 상호운용이 크게 개선되었습니다.