#引用计数 #垃圾回收 #循环 #rc #gc

gcmodule

受 CPython 的 gc 实现启发的循环垃圾回收

8 个版本

0.3.3 2020年4月12日
0.3.2 2020年4月10日
0.2.3 2020年3月9日
0.1.2 2020年3月2日

#690 in 内存管理

46 每月下载量
litto 中使用

MIT 许可证

105KB
2K SLoC

gcmodule

Documentation Build Status

CPython 实现启发的垃圾回收。

此库提供了一个类型 Cc<T>。它提供了类似于 stdlib Rc<T> 的共享引用计数指针。与 Rc 不同,Cc 中的引用循环可以被收集。

如果所有值都可以通过引用计数来释放,该库使用的收集器不需要额外内存。这与一些其他实现不同,这些实现需要手动收集来释放收集器使用的额外内存。

示例

use gcmodule::{Cc, Trace};
use std::cell::RefCell;

type List = Cc<RefCell<Vec<Box<dyn Trace>>>>;
let a: List = Default::default();
let b: List = Default::default();
a.borrow_mut().push(Box::new(b.clone()));
b.borrow_mut().push(Box::new(a.clone())); // Form a cycle.
drop(a);
drop(b); // Internal values are not dropped due to the cycle.
gcmodule::collect_thread_cycles(); // Internal values are dropped.

对于自定义结构,它们需要实现 Trace 接口。可以通过 #[derive(Trace)] 来完成。

use gcmodule::{Cc, Trace};
use std::cell::RefCell;

#[derive(Trace, Default)]
struct List(RefCell<Vec<Box<dyn Trace>>>);
{
    let a: List = Default::default();
    let b: List = Default::default();
    a.borrow_mut().push(Box::new(b.clone()));
    b.borrow_mut().push(Box::new(a.clone()));
}
assert_eq!(gcmodule::collect_thread_cycles(), 2); // 2 values are collected.

有关更多示例和技术细节,请参阅 文档

类似项目

bacon-rajan-cc v0.3

  • 两者都是引用计数,具有循环垃圾回收。
  • 两者主要都是单线程的,并且是停止世界的。
  • 主要 API,如 Cc<T>Trace,是相似的,甚至兼容。
  • gcmodule 在概念上更简单。不需要“颜色”概念。
  • gcmodule 为多线程环境提供了 ThreadedCc<T>
  • bacon-rajan-cc 即使引用计数逻辑上降至0,也需要手动收集以释放GC元数据(但不包括跟踪对象)。有关详细信息,请参阅此提交信息

rcgc v0.1

  • rcgc 采用了一种新颖的方法——收集器持有强引用,而其他地方使用弱引用。
  • 因此,即使对象的引用计数(逻辑上)降至0,rcgc 也需要手动收集以释放实际对象。

依赖项

~0–540KB