6个版本 (破坏性更新)

0.5.0 2024年8月6日
0.4.0 2024年7月29日
0.3.0 2024年7月9日
0.2.0 2023年5月25日
0.1.0 2023年3月14日

#88 in 内存管理

Download history 68/week @ 2024-07-03 48/week @ 2024-07-10 109/week @ 2024-07-24 169/week @ 2024-07-31 44/week @ 2024-08-07

每月322次下载

MIT/Apache

205KB
5K SLoC

rust-cc

Build status main branch Build status dev branch docs.rs Crates.io Version License

基于循环收集的Rust程序快速垃圾收集器。

此crate提供了一个Cc(循环收集)智能指针,它基本上是一个Rc,可以自动检测和释放引用循环。如果没有引用循环,则Cc的行为就像Rc一样,并在引用计数器降至零时立即释放。

目前,循环收集器不是并发的。因此,Cc不实现Send也不实现Sync

特性

  • 可完全通过Cargo特性自定义
  • 自动执行集合
  • 最终化
  • 弱指针
  • 清理器
  • 无 std 支持(由于线程局部存储需要 ELF TLS)

基本用法示例

#[derive(Trace, Finalize)]
struct Data {
    a: Cc<u32>,
    b: RefCell<Option<Cc<Data>>>,
}

// Rc-like API
let my_cc = Cc::new(Data {
    a: Cc::new(42),
    b: RefCell::new(None),
});

let my_cc_2 = my_cc.clone();
let pointed: &Data = &*my_cc_2;
drop(my_cc_2);

// Create a cycle!
*my_cc.b.borrow_mut() = Some(my_cc.clone());

// Here, the allocated Data instance doesn't get immediately deallocated, since there is a cycle.
drop(my_cc);
// We have to call the cycle collector
collect_cycles();
// collect_cycles() is automatically called from time to time when creating new Ccs,
// calling it directly only ensures that a collection is run (like at the end of the program)

Finalize特性生成的派生宏会生成一个空最终化器。要编写自定义最终化器,请手动实现Finalize特性

impl Finalize for Data {
    fn finalize(&self) {
        // Finalization code called when a Data object is about to be deallocated
        // to allow resource clean up (like closing file descriptors, etc)
    }
}

有关更多信息,请参阅文档

集合算法

主要思想是利用引用计数器中包含的信息发现根(即肯定不是垃圾的对象),而不是从其他来源获取它们。

通常,在垃圾回收语言中,运行时始终有一种方法可以知道哪些对象是根(知道根可以使垃圾收集器知道哪些对象仍然可由程序访问,因此可以和不可以释放)。
然而,由于Rust没有运行时,这些信息不可用!因此,为Rust程序实现的Rust中的垃圾收集器在确定哪些对象可以释放以及哪些不可以释放时非常困难,因为它们仍然可能被程序访问。

rust-cc 使用引用计数器,能够在运行时查找根节点并进行收集,从而消除了不断跟踪它们的需要。这也是为什么标准 RefCell(而不是自定义的)可以在循环收集对象内部安全地使用内部可变性。

此外,实现的循环收集器通常比标记-清除垃圾收集器在大(且碎片化)堆上更快,因为每次运行时不需要遍历整个堆。

如果您想阅读源代码,算法在 CONTRIBUTING.md 中有更深入的描述。

基准测试

比较 rust-cc 与其他收集器的基准测试可以在 https://github.com/frengor/rust-cc-benchmarks 找到。

许可证

本项目可使用以下任一许可证:

供您选择。

除非您明确声明,否则根据 Apache-2.0 许可证定义,您提交给该软件包的任何有意包含的贡献,将根据上述条款双重许可,不附加任何其他条款或条件。

依赖项

~0.3–0.8MB
~19K SLoC