5个版本
0.2.1 | 2024年6月2日 |
---|---|
0.2.0 | 2024年6月2日 |
0.1.2 | 2023年8月25日 |
0.1.1 | 2023年8月14日 |
0.1.0 | 2023年8月14日 |
#80 在 内存管理
每月 38 次下载
140KB
2.5K SLoC
dumpster
:Rust的周期跟踪垃圾回收器
dumpster
是一个Rust的周期检测垃圾回收器。它检测无法到达的分配并自动释放它们。
为什么你应该使用这个包?
简而言之,dumpster
提供了可用性、性能和灵活性的绝佳组合。
dumpster
的API是std
的引用计数共享分配(Rc和
Arc
)的直接替换。- 它性能非常好,并内置了线程局部和并发垃圾回收的实现。
- 垃圾回收分配内的引用结构没有限制(引用可以指向任何方式)。
- 使用提供的derive宏可以轻松地将自定义类型标记为可回收。
- 你甚至可以将
?Sized
数据存储在垃圾回收指针中!
工作原理
dumpster
与大多数跟踪垃圾回收器不同。其他GC会跟踪一组根节点,然后可以使用这些根节点执行清理操作,确定哪些分配是可达的,哪些是不可达的。相反,dumpster
通过周期检测算法扩展了引用计数的垃圾回收(如std::rc::Rc
),使其能够有效地清理自引用数据结构。
要深入了解,请查看这篇博客文章。
该库包含的内容
dumpster
实际上包含两个垃圾回收器实现:模块 unsync
中的线程局部、非Send
垃圾回收器和模块 sync
中的线程安全垃圾回收器。这些垃圾回收器可以安全地混合使用。
这个库还提供了一个用于创建自定义可收集类型的 derive 宏。
示例
use dumpster::{Collectable, unsync::Gc};
#[derive(Collectable)]
struct Foo {
ptr: RefCell<Option<Gc<Foo>>>,
}
// Create a new garbage-collected Foo.
let foo = Gc::new(Foo {
ptr: RefCell::new(None),
});
// Insert a circular reference inside of the foo.
*foo.ptr.borrow_mut() = Some(foo.clone());
// Render the foo inaccessible.
// This may trigger a collection, but it's not guaranteed.
// If we had used `Rc` instead of `Gc`, this would have caused a memory leak.
drop(foo);
// Trigger a collection.
// This isn't necessary, but it guarantees that `foo` will be collected immediately (instead of
// later).
dumpster::unsync::collect();
安装
要安装,只需将 dumpster
添加到您的项目依赖项中。
[dependencies]
dumpster = "0.1.2"
可选功能
dumpster
有两个可选功能:derive
和 coerce-unsized
。
derive
默认启用。它启用了 Collectable
的 derive 宏,使用户能够轻松实现自己的可收集类型。
use dumpster::{unsync::Gc, Collectable};
use std::cell::RefCell;
#[derive(Collectable)] // no manual implementation required
struct Foo(RefCell<Option<Gc<Foo>>>);
let my_foo = Gc::new(Foo(RefCell::new(None)));
*my_foo.0.borrow_mut() = Some(my_foo.clone());
drop(my_foo); // my_foo will be automatically cleaned up
coerce-unsized
默认禁用。它启用了每个垃圾回收器的 CoerceUnsized
实现,使得能够方便地使用 Gc
与 !Sized
类型。
use dumpster::unsync::Gc;
// this only works with "coerce-unsized" enabled while compiling on nightly Rust
let gc1: Gc<[u8]> = Gc::new([1, 2, 3]);
要使用 coerce-unsized
,请编辑您的 Cargo.toml
文件以包含此功能。
[dependencies]
dumpster = { version = "0.1.2", features = ["coerce-unsized"]}
许可协议
此代码受 Mozilla 公共许可证(版本 2.0)许可。有关更多信息,请参阅 LICENSE.md。
依赖项
~0.4–6MB
~14K SLoC