Garbage Collection for Rust: The Finalizer Frontier
Jacob Hughes, Laurence Tratt
TL;DR
Alloy presents a Rust-oriented GC that reuses destructors as finalizers via a $Gc<T>$ API, integrating a conservative backend ($BDWGC$) and addressing classic finalizer challenges with Finalizer Safety Analysis, Premature Finalizer Prevention, and Finalizer Elision, plus a separate finalizer thread. The approach leverages Rust’s ownership guarantees to support most destructors as finalizers while ensuring safety in the presence of cycles and cross-thread execution. Empirical evaluation shows a modest wall-clock overhead (~5%) with variable memory footprints and clear benefits from finalizer elision, though performance is context-dependent relative to Arena-based or RC-based approaches. The work outlines practical pathways for integrating GC into Rust codebases and highlights both the potential gains and the need for further refinement to reach production readiness.
Abstract
Rust is a non-Garbage Collected (GCed) language, but the lack of GC makes expressing data-structures that require shared ownership awkward, inefficient, or both. In this paper we explore a new design for, and implementation of, GC in Rust, called Alloy. Unlike previous approaches to GC in Rust, Alloy allows existing Rust destructors to be automatically used as GC finalizers: this makes Alloy integrate better with existing Rust code than previous solutions but introduces surprising soundness and performance problems. Alloy provides novel solutions for the core problems: finalizer safety analysis rejects unsound destructors from automatically being reused as finalizers; finalizer elision optimises away unnecessary finalizers; and premature finalizer prevention ensures that finalizers are only run when it is provably safe to do so.
