2个版本
0.1.1 | 2019年9月26日 |
---|---|
0.1.0 | 2019年9月26日 |
#42 in #collector
3KB
PGC
PGC是一个基于Rust构建的精确跟踪垃圾收集器,具有并行标记和标记-清除算法。
如何使用
要将pgc-derive包含到您的项目中,请将以下内容添加到您的Cargo.toml中
[dependencies]
pgc = "*"
这可以像Rc一样使用,除了内部可变性。
放置在Gc
和Rooted
内部的类型必须实现GcObject
和Send
。
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