#垃圾回收 #gc #垃圾 #收集

nightly sys bronze_gc

Bronze 垃圾回收器用于 Rust。此版本仅包括创建和使用 GC 引用的 API;它实际上不进行任何收集。仅用于实验目的。

4 个版本 (2 个破坏性更新)

0.2.1 2022年1月28日
0.2.0 2022年1月19日
0.1.0 2021年4月11日
0.0.1 2021年3月26日

#684 in 内存管理

每月 25 次下载

MIT 许可

37KB
855

Bronze

安装

要使用 Bronze,您必须使用 nightly Rust 工具。要安装它们,请在命令行上运行 rustup default nightly

使用方法

有时,Rust 中所有变量都有一个所有者的要求可能难以解决。例如,在 Rust 中实现双向链表非常困难,因为每个节点必须被引用两次。此外,特别是对于正在学习 Rust 的人来说,暂时避免“每个变量都有一个所有者”的限制可能更容易。

Bronze 通过引入一个新的智能指针类型 GcRef 来放宽 Rust 的一些限制,该类型描述了对垃圾回收堆位置的指针。在使用 Bronze 时,位于 上的数据具有所有常规 Rust 所有者要求。然而,Bronze 允许将数据移动到 。如果类型 T 的值位于堆上,Bronze 允许多个 GcRef<T> 引用对该值。

例如,没有 Bronze,我们必须仔细管理引用和生存期

pub struct IntContainer {
    n: i32,
}

pub fn set(c: &mut IntContainer, n: i32) {
    c.n = n;
}

pub fn test() {
    let c1 = IntContainer{n: 42};
    let mut c2 = c1;
    
    // Can't use c1 anymore because it's been moved to c2
    set(&mut c2, 42);
}

使用 Bronze,可以通过智能指针引用不是 Copy 的类型,这些智能指针是 Copy。可以通过 borrow()borrow_mut 获取临时不可变和不可变借用;这些实现 Deref,允许方便地访问。

// 
#[derive(Trace, Finalize)]
pub struct IntContainer {
    n: i32,
}

pub fn set(mut c: GcRef<IntContainer>, n: i32) {
    c.borrow_mut().n = n;
}

pub fn test() {
    let c1 = GcRef::new(IntContainer{n: 42});
    let c2 = c1; 
    // Now c1 and c2 both reference the same object.
    
    set(c2, 42);
    set(c1, 43);
    // Now they both reference an object with value 43.
}

要创建一个新的 GcRef<T>,调用 GcRef::new(e),其中 e 是一个表达式,其值你想在 GC 堆上。

高级使用

如果您需要从GC堆中删除数据,您可以使用GcNullableRef而不是GcRef。您可以使用Gc::new_nullable来创建一个。 GcNullableRef类似于GcRef,但增加了一个remove方法。第一次调用remove将返回一个填充了之前在GC堆中的数据的Option。后续对remove的调用将返回None。

安全性

Bronze的早期版本允许用户获取GC对象的多个可变引用。这现在不应再成为可能;相反,Bronze动态跟踪借用(使用与RefCell中使用的机制非常相似的机制)。要获取GC对象的不可变或可变借用引用,请在GcRef上调用borrow()borrow_mut()

实验性实现

此实现是实验性的。特别是,收集器将不会运行;请注意,您最终会耗尽内存。然而,当前版本适合实验和原型设计。

依赖项

~0–2.1MB
~41K SLoC