핵심 요약
- 가비지 컬렉터가 없어 빠른 성능을 자랑하는 러스트(Rust)에 직접 가비지 컬렉터를 구현한 개발자의 프로젝트가 공개되었습니다.
- 러스트의 표준 참조 카운터(Rc, Arc)가 해결하지 못하는 순환 참조 메모리 누수 문제를 해결하기 위해 그래프 이론 기반의 감지 알고리즘을 고안했습니다.
- 스택 스캔이 불가능하고 타입 정보가 런타임에 사라지는 등 러스트 고유의 난관을 뚫고 실제 동작하는 라이브러리(dumpster)로 배포까지 마쳤습니다.
요약 가비지 컬렉터(GC)가 없는 것을 가장 큰 특징이자 무기로 내세우는 프로그래밍 언어 러스트(Rust)에 직접 가비지 컬렉터를 구현해 넣은 개발자의 유쾌한 삽질기가 개발자 커뮤니티에서 소소하게 화제를 모았습니다.
작성자는 여름 동안 시간이 남아 "메모리 안전성이 보장된다는 언어에서 코어 덤프를 들여다보는 것보다 알찬 여름휴가가 어디 있겠냐"며 농담 섞인 소회를 밝혔습니다. 다른 언어들이 러스트를 닮아가는 현상을 '게화(Carcinization)'라고 부른다면, 러스트가 자바(Java)처럼 변해가는 것은 '카페인화(Caffeination)'라고 불러야 하냐며 너스레를 떨기도 했습니다.
러스트는 본래 소유권(Ownership)과 빌림 검사기(Borrow Checker) 시스템을 통해 컴파일 타임에 메모리 안전성을 강제하므로 별도의 런타임 GC를 두지 않습니다. 표준 라이브러리 차원에서 참조 횟수를 세는 `Rc`나 멀티스레드용 `Arc`를 제공하긴 하지만, 객체들이 서로를 가리키는 순환 참조(Cyclic reference)가 발생하면 메모리를 영원히 해제하지 못하는 치명적인 한계가 존재합니다. 작성자는 "참조 카운팅만으로 다 해결됐다면 오라클의 수많은 엔지니어들은 진작 실직했을 것"이라며 순환 참조까지 깔끔하게 감지하고 수거하는 GC 라이브러리 'dumpster'를 제작하게 된 배경을 설명했습니다.
하지만 러스트에서 완전한 GC를 만드는 과정은 결코 쉽지 않았습니다. 러스트에서는 값이 메모리 상에서 이동(Move)할 때 이를 객체 내부에서 감지할 수 있는 기능이 없어 스택을 온전히 스캔하기 어렵습니다. 또한 런타임에 타입 정보가 지워지는 모노모피즘(Type erasure) 특성과 크기가 정해지지 않은 가변 크기 타입(`?Sized`) 지원 등 까다로운 제약이 따랐습니다. 작성자는 메모리 할당 상태를 방향 그래프(Allocation Graph)로 모델링하고, 루트 노드로부터의 도달 가능성을 서브그래프의 진입 차수(Indegree) 비교 방식으로 검증하는 아이디어를 적용해 스택 스캔 없이도 도달 불가능한 순환 메모리를 판별해 내는 데 성공했다고 밝혔습니다. 해당 프로젝트는 오픈소스로 공개되어 패키지 매니저(crates.io)를 통해 실제로 내려받을 수 있는 상태입니다.
Sponsored · 광고