2个版本

0.1.1 2019年9月26日
0.1.0 2019年9月26日

#42 in #collector

MIT 许可证

3KB

PGC

PGC是一个基于Rust构建的精确跟踪垃圾收集器,具有并行标记和标记-清除算法。

如何使用

要将pgc-derive包含到您的项目中,请将以下内容添加到您的Cargo.toml中

[dependencies]
pgc = "*"

这可以像Rc一样使用,除了内部可变性。

放置在GcRooted内部的类型必须实现GcObjectSend

use pgc::*;

struct Foo {
    x: Gc<i32>,
    y: i32
}

unsafe impl GcObject for Foo {
    fn references(&self) -> Vec<Gc<dyn GcObject>> {
        let mut v: Vec<Gc<dyn GcObject>> = vec![];
        v.push(self.x);
        v
    }
}

要使用Gc,只需调用Gc::new

let foo = Gc::new(Foo {...});

GC不会扫描程序堆栈以查找根对象,因此您需要显式添加根

let foo = Gc::new(Foo {...});
add_root(foo);
... // do something with `foo`
remove_root(foo);
// Or use `Rooted` struct that will unroot object automatically:
let foo = Rooted:new(Foo {...});

问题

  • 当前的收集算法不是完全线程安全的,对于在多个线程中收集对象,我们应该提供一些平台相关的代码来暂停线程(停止世界) 停止世界机制似乎工作正常。
  • 不是完全增量。标记可以并行执行,但如果你想要标记小内存块,你应该在你的代码中调用gc_mark
  • GC无法正确扫描程序堆栈以查找对象,因为Rust的动态分发不完全允许将某些随机指针转换为特例对象,因此你应该显式地根和取消根对象。

依赖项

~1.5MB
~37K SLoC