#垃圾回收 # #gc #zero #reference #object #unsafe

safe-gc

一个无任何unsafe代码和无依赖的垃圾回收库

3个稳定版本

1.1.1 2024年7月15日
1.0.0 2024年1月31日

#96内存管理

Download history 225/week @ 2024-07-15 11/week @ 2024-07-29

每月236次下载

MIT/Apache

45KB
643

safe-gc

一个无任何unsafe代码的Rust垃圾回收库

build status Documentation Status

关于

safe-gc实现了一个Rust的垃圾回收库,无任何unsafe代码和无依赖。它甚至还在顶部有一个forbid(unsafe_code)指令!

附加功能

  • 允许构建和收集任意堆图,包括循环。它不对堆内GC管理的对象之间的引用形状施加任何所有权的层次结构或类似的东西。

  • 在其API中利用Rust的所有权和借用:如果您有一个&mut Heap,您可以获取堆中对象的可变访问。例如,它不会强制堆中的所有内容都进入RefCell,也不会只提供GC管理的对象的共享引用,或类似的东西。

  • 允许构建多个独立的GC堆,这些堆可以独立收集。

  • 允许在堆内分配任意数量的异构类型。例如,您可以在堆内分配ConsTree对象。堆不限于仅包含单个、统一的T类型的GC对象。

  • 使用Rust的常规、旧的Drop特质进行无弹性的GC对象最终化。无需担心意外解除GC对象已回收的指针或复活即将回收的对象。

然而,safe-gc并不是一个特别高性能的垃圾回收器。

使用方法

  • 定义由GC管理的类型。

  • 使用Gc<T>定义从一个GC类型到另一个GC类型的引用。

  • 为您的GC管理类型实现Trace

  • 创建一个或多个Heap

  • 在您的Heap中分配对象。

  • 持有GC根节点 Root<T>

  • 让垃圾回收器回收不可达的对象!

示例

use safe_gc::{Collector, Gc, Heap, Trace};

// Define a GC-managed tree of `T` values.
struct Tree<T: Trace> {
    value: Gc<T>,

    // A cyclic parent pointer.
    parent: Option<Gc<Tree<T>>>,

    // Left and right subtrees.
    left: Option<Gc<Tree<T>>>,
    right: Option<Gc<Tree<T>>>,
}

// Report each of the GC references within a `Tree` to the
// collector.
//
// See the `Trace` docs for more details.
impl<T: Trace> Trace for Tree<T> {
    fn trace(&self, collector: &mut Collector) {
        collector.edge(self.value);
        if let Some(parent) = self.parent {
            collector.edge(parent);
        }
        if let Some(left) = self.left {
            collector.edge(left);
        }
        if let Some(right) = self.right {
            collector.edge(right);
        }
    }
}

// Another GC type!
struct Cat {
    cuteness: u32,
    cat_tree: Option<Gc<Tree<Cat>>>,
}

impl Trace for Cat {
    fn trace(&self, collector: &mut Collector) {
        if let Some(tree) = self.cat_tree {
            collector.edge(tree);
        }
    }
}

// Create a new GC heap!
let mut heap = Heap::new();

// Allocate some objects in the heap!
let momo = heap.alloc(Cat {
    cuteness: u32::MAX,
    cat_tree: None,
});
let tree = heap.alloc(Tree {
    value: momo.unrooted(),
    parent: None,
    left: None,
    right: None,
});

// Create a bunch of garbage! Who cares!
for _ in 0..100 {
    let _ = heap.alloc(Tree {
        value: momo.unrooted(),
        parent: None,
        left: None,
        right: None,
    });
}

// Read data from objects in the heap!
let cuteness = heap[&momo].cuteness;
assert_eq!(cuteness, u32::MAX);

// Mutate objects in the heap!
heap[&momo].cat_tree = Some(tree.into());

// Garbage collections will happen automatically, as necessary, but you can also
// force a collection, if you want!
heap.gc();

为什么?

safe-gc 在 Rust 垃圾回收库的设计空间中无疑是一个有趣的点——也许甚至是有用的!

此外,这也很有趣!

至少,你不必担心这里任何 unsafe 代码的正确性,因为这里没有。只要 Rust 语言及其标准库是可靠的,这个库也是如此。

无运行时依赖