6 个版本 (破坏性)
0.5.0 | 2023年12月24日 |
---|---|
0.4.0 | 2023年10月21日 |
0.3.0 | 2023年1月2日 |
0.2.0 | 2022年4月2日 |
0.1.1 | 2021年6月14日 |
120 在 内存管理 中
每月 33 次下载
130KB
1.5K SLoC
CactusRef
单线程、周期感知、引用计数指针。'Rc' 代表 '引用计数'。
如果我们在智能指针中放一个哈希表,会怎么样呢?
CactusRef 是一个单线程、引用计数的智能指针,可以在不使用弱指针的情况下处理循环。从 std
中的 Rc
可能难以使用,因为创建 Rc
的循环会导致内存泄漏。
CactusRef 是 std::rc::Rc
的近似直接替换品,它引入了额外的 API,用于在 Rc
的图中记录所有权关系。
结合 CactusRef 的 采用 API 以跟踪对象图中的链接并驱动垃圾回收,以及 Rust 的 析构粘合剂,实现了一种追踪垃圾收集器。CactusRefs 的图检测到连接的 CactusRefs 图中的局部循环,并且不需要像在追踪垃圾收集器中通常所需的那样扫描整个堆。
CactusRefs 的循环在它们不再从循环外部可达时确定性地收集和释放。
自引用数据结构
CactusRef 可以用于实现自引用数据结构,如双向链表,而不需要使用弱引用。
用法
将以下内容添加到您的 Cargo.toml
[dependencies]
cactusref = "0.5.0"
CactusRef 主要是一个用于替换 std::rc::Rc
的直接替换品,可以像这样使用
use cactusref::Rc;
let node = Rc::new(123_i32);
let another = Rc::clone(&node);
assert_eq!(Rc::strong_count(&another), 2);
let weak = Rc::downgrade(&node);
assert!(weak.upgrade().is_some());
或者开始创建自引用数据结构,如下
use std::cell::RefCell;
use cactusref::{Adopt, Rc};
struct Node {
next: Option<Rc<RefCell<Node>>>,
data: i32,
}
let left = Node { next: None, data: 123 };
let left = Rc::new(RefCell::new(left));
let right = Node { next: Some(Rc::clone(&left)), data: 456 };
let right = Rc::new(RefCell::new(right));
unsafe {
// bookkeep that `right` has added an owning ref to `left`.
Rc::adopt_unchecked(&right, &left);
}
left.borrow_mut().next = Some(Rc::clone(&right));
unsafe {
// bookkeep that `left` has added an owning ref to `right`.
Rc::adopt_unchecked(&left, &right);
}
let mut node = Rc::clone(&left);
// this loop will print:
//
// > traversing ring and found node with data = 123
// > traversing ring and found node with data = 456
// > traversing ring and found node with data = 123
// > traversing ring and found node with data = 456
// > traversing ring and found node with data = 123
for _ in 0..5 {
println!("traversing ring and found node with data = {}", node.borrow().data);
let next = if let Some(ref next) = node.borrow().next {
Rc::clone(next)
} else {
break;
};
node = next;
}
assert_eq!(Rc::strong_count(&node), 3);
drop(node);
drop(left);
drop(right);
// All members of the ring are garbage collected and deallocated.
成熟度
CactusRef 是实验性的。这个包有一些限制
- CactusRef 仅在 nightly 版本中可用。
- 循环检测需要使用 不安全代码。
CactusRef 是 std::rc::Rc
的非平凡扩展,并且尚未证明是安全的。尽管 CactusRef 会尽力检测悬垂的 Rc
并终止程序,但这个包可能是不安全的。
no_std
CactusRef 与 no_std
兼容,默认启用对 std
的可选依赖。CactusRef 依赖于 alloc
包。
包功能
所有功能默认启用。
许可证
CactusRef 使用 MIT 许可证 (c) Ryan Lopopolo。
CactusRef 来自 Rust 标准库中的 Rc
,位于 f586d79d
,该库使用 MIT 许可证和 Apache 2.0 许可证双重许可。
依赖关系
~725KB
~10K SLoC