4个版本
0.2.0 | 2021年8月13日 |
---|---|
0.1.2 | 2020年7月20日 |
0.1.1 | 2020年6月8日 |
0.1.0 | 2020年6月6日 |
#344 in 内存管理
在 3 个crate中(直接使用2个) 使用
145KB
3K SLoC
shredder
shredder
是一个提供垃圾回收智能指针的库:Gc
。这在需要共享访问某些数据,但数据的结构具有不可预测的循环时非常有用。(因此Arc不合适。)
shredder
具有以下功能
- 安全:实时检测错误条件,并保护您免受未定义行为的影响
- 人体工程学设计:无需手动管理根,只需一个常规智能指针
- 支持解引用:在可能的情况下,
DerefGc
提供垃圾回收和Deref
智能指针 - 准备进行无恐惧的并发:在多线程环境中工作,对于需要原子操作的情况,有
AtomicGc
- 有限的停止世界:常规处理很少被打断
- 无缝销毁:对于
'static
数据,有常规的drop
- 清洁最终化:对于非
'static
数据,有可选的finalize
- 并发收集:在后台进行收集,提高性能
- 并发销毁:在后台运行析构函数,提高性能
shredder
具有以下限制
- 受保护访问:访问
Gc
数据需要获取一个保护器(尽管在许多情况下可以使用DerefGc
来避免这种情况) - 多个收集器:仅支持单个全局收集器
- 无法处理
Rc/
Arc
:要求所有Gc
对象具有简单的所有权语义 - 收集优化速度,而非内存使用:
Gc
和内部元数据很小,但在收集过程中存在膨胀(将修复!) - 不支持 no-std:收集器需要线程和其他
std
功能(将修复!)
入门指南
这里有一个简单的示例,展示了 Gc
的工作原理
use std::cell::RefCell;
use shredder::{
number_of_active_handles, number_of_tracked_allocations, run_with_gc_cleanup, Gc, Scan,
};
#[derive(Scan)]
struct Node {
data: String,
directed_edges: Vec<Gc<RefCell<Node>>>,
}
fn main() {
// Using `run_with_gc_cleanup` is good practice, since it helps ensure destructors are run
run_with_gc_cleanup(|| {
let a = Gc::new(RefCell::new(Node {
data: "A".to_string(),
directed_edges: Vec::new(),
}));
let b = Gc::new(RefCell::new(Node {
data: "B".to_string(),
directed_edges: Vec::new(),
}));
// Usually would need `get` for `Gc` data, but `RefCell` is a special case
a.borrow_mut().directed_edges.push(b.clone());
b.borrow_mut().directed_edges.push(a);
// We now have cyclical data!
});
// Everything was cleaned up!
assert_eq!(number_of_tracked_allocations(), 0);
assert_eq!(number_of_active_handles(), 0);
}
如果你在尝试这个并遇到问题,请创建一个 Github issue。最终将会有一个常见问题解答。
需要帮助!
如果您想帮助 shredder
,请随时联系。我在 Rust Discord 上是 @Others。或者只需寻找标记为 help wanted
或 good first issue
的问题。
依赖项
~4MB
~81K SLoC