dumpster: A cycle-tracking garbage collector for Rust

dumpster is an cycle-detecting garbage collector for Rust. It detects unreachable allocations and automatically frees them.

Why should you use this crate?

In short, dumpster offers a great mix of usability, performance, and flexibility.

How it works

dumpster is unlike most tracing garbage collectors. Other GCs keep track of a set of roots, which can then be used to perform a sweep and find out which allocations are reachable and which are not. Instead, dumpster extends reference-counted garbage collection (such as std::rc::Rc) with a cycle-detection algorithm, enabling it to effectively clean up self-referential data structures.

For a deeper dive, check out this blog post.

What this library contains

dumpster actually contains two garbage collector implementations: one thread-local, non-Send garbarge collector in the module unsync, and one thread-safe garbage collector in the module sync. These garbage collectors can be safely mixed and matched.

This library also comes with a derive macro for creating custom collectable types.

Examples

```rust use dumpster::{Collectable, unsync::Gc};

[derive(Collectable)]

struct Foo { ptr: RefCell>>, }

// Create a new garbage-collected Foo. let foo = Gc::new(Foo { ptr: RefCell::new(None), });

// Insert a circular reference inside of the foo. *foo.ptr.borrow_mut() = Some(foo.clone());

// Render the foo inaccessible. // This may trigger a collection, but it's not guaranteed. // If we had used Rc instead of Gc, this would have caused a memory leak. drop(foo);

// Trigger a collection. // This isn't necessary, but it guarantees that foo will be collected immediately (instead of // later). dumpster::unsync::collect(); ```

Installation

To install, simply add dumpster as a dependency to your project.

toml [dependencies] dumpster = "0.1.0"

Optional features

dumpster has two optional features: derive and coerce-unsized.

derive is enabled by default. It enables the derive macro for Collectable, which makes it easy for users to implement their own collectable types.

```rust use dumpster::{unsync::Gc, Collectable}; use std::cell::RefCell;

[derive(Collectable)] // no manual implementation required

struct Foo(RefCell>>);

let myfoo = Gc::new(Foo(RefCell::new(None))); *myfoo.0.borrowmut() = Some(myfoo.clone());

drop(myfoo); // myfoo will be automatically cleaned up ```

coerce-unsized is disabled by default. This enables the implementation of CoerceUnsized for each garbage collector, making it possible to use Gc with !Sized types conveniently.

```rust use dumpster::unsync::Gc;

// this only works with "coerce-unsized" enabled while compiling on nightly Rust let gc1: Gc<[u8]> = Gc::new([1, 2, 3]); ```

To use coerce-unsized, edit your installation to Cargo.toml to include the feature.

toml [dependencies] dumpster = { version = "0.1.0", features = ["coerce-unsized"]}

License

This code is licensed under the GNU GPLv3. For more information, refer to LICENSE.md.