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个) 使用

MIT 许可证

145KB
3K SLoC

shredder

Version Docs License CircleCI Coverage Status Dependencies

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