Garbage collection for Rust: The finalizer frontier

Rust’s Design Goals vs. Garbage Collection

  • Some argue GC “defeats the point” of Rust, whose core value is memory safety without a runtime GC via ownership and borrow checking.
  • Others counter that Rust’s benefits go far beyond “no GC” (enums, traits, borrow checking, tooling, startup time, ecosystem), so an optional GC doesn’t undermine its identity.
  • Several worry that if a GC library becomes the “easy” option, it could spread through dependencies and erode Rust’s low-level niche.

Intended Use Cases for GC in Rust

  • Implementing language runtimes (JS engines, VMs) and complex object graphs with shared/cyclic references are cited as prime candidates.
  • For most Rust code, library-level GC would be too awkward to use pervasively and is seen as a specialized tool, similar to Rc/Arc.
  • Some suggest GC specifically for non‑critical business logic, keeping performance‑sensitive or embedded parts using standard Rust ownership.

Conservative vs Precise GC and Rust Semantics

  • The discussed system (Alloy) is conservative because Rust allows pointers to be turned into integers and back (including in safe code via usize and in unsafe code via casts).
  • Critics note conservative GCs can’t move objects, limiting compaction and modern GC optimizations. They’re viewed as “stuck behind the frontier.”
  • There’s debate over future pointer provenance rules: strict provenance might help precise GC, but today integer–pointer roundtrips and even exotic schemes (e.g. XORing pointers) mean a conservative GC can theoretically miss live objects or leak memory.

Finalizers, Resurrection, and Safety

  • Finalizers are described as attractive but fundamentally fraught; mainstream GC languages advise avoiding them except in rare, expert cases.
  • An example is given of object resurrection in a finalizer to handle locking, illustrating how subtle and error-prone finalization logic can be.

Async/Await, Leaks, and Desire for GC

  • Some see Rust’s async/await model as a strong argument for GC (or even a “separate async Rust”), citing borrow-checker pain and lifetime issues across async boundaries.
  • Others respond that active futures or careful use of Arc/borrows might suffice, though safe Rust currently can’t express all desired scoped-task patterns.

Alternatives and Ecosystem Comparisons

  • Alternatives raised: arenas, handle-based structures, Rc/Arc, GhostCell, and reference counting (Swift-style). Arenas are seen as powerful but somewhat clumsy in Rust today.
  • Some suggest just using Go, Java, C#, OCaml, or Scala if you want GC + strong types, but others say Rust uniquely combines its type system, performance model, and tooling.