5个版本
0.2.2 | 2021年5月4日 |
---|---|
0.2.1 | 2021年5月4日 |
0.2.0 | 2019年11月19日 |
0.1.1 | 2019年5月11日 |
0.1.0 | 2019年5月7日 |
#426 in 内存管理
160KB
3K SLoC
gc-arena和gc-sequence
该仓库包含gc-arena
和gc-sequence
这两个crate,它们为Rust提供了垃圾收集的竞技场以及与之安全交互的方法。
这些crate仍然相当实验性且为WIP,但它们确实可以工作,并提供真正安全的垃圾收集指针。
gc-arena
gc-arena
crate及其辅助crate gc-arena-derive
提供在封闭的"竞技场"内的安全分配和带有循环检测的垃圾收集。该系统有两个技术使其稳健
-
使用
Collect
trait跟踪垃圾收集对象,该trait必须正确实现以确保找到所有可到达的对象。因此,该trait是unsafe
,但可以通过过程宏安全地实现,而gc-arena-derive
提供了这样的安全过程宏。 -
为了进行垃圾回收,垃圾回收器必须首先有一个“根”对象的列表,这些对象已知是可以到达的。在我们的情况下,
gc-arena
的使用者选择一个根对象作为区域,但这不足以进行安全的垃圾回收。如果垃圾回收发生在Rust栈上有垃圾收集指针的情况下,这些指针也需要被视为“根”对象,以防止内存不安全。gc-arena
通过严格限制垃圾收集指针可以存储的位置以及它们可以存活的时间来解决这个问题。该区域只能通过一个接受回调的单一mutate
方法访问,并且这个回调内的所有垃圾收集指针都被标记为具有唯一的不可变生命周期。因此,当在mutate
方法外部时,Rust借用检查器确保堆栈上任何地方都不可能存在垃圾收集指针,也不可能将它们偷偷带出区域根对象。由于所有指针都可以证明是从单个根对象可达的,因此可以安全地进行垃圾回收。
换句话说,gc-arena
包并没有为Rust添加一个全局可访问的垃圾收集器,而只是在隔离的垃圾收集区域中允许有限的垃圾收集。所有垃圾收集指针必须永远只生活在该区域内部,并且不同区域的指针被阻止存储在错误的区域。
gc-sequence
尽管gc-arena
包仍然有用,但它非常有限。由于垃圾回收只能在mutate
调用的之间进行,任意长的mutate
调用可能会阻止垃圾回收任意长的时间。
gc-sequence
通过在垃圾收集区域之上提供类似futures
的API来尝试减轻这个问题。它允许用户通过组合子构建类似futures
的状态机,并通过反复调用Sequence::step
来驱动这些状态机向前发展。生成的Sequence
状态机本身实现了Collect
,因此提供的区域包装器可以安全地执行任意长时间的Sequence
,在Sequence::step
调用之间进行垃圾回收。通过这种方式,Sequence
特质成为表达垃圾收集器“安全点”的一种方式,在这些点上可以安全地进行收集。
用例
这些包主要是作为一种在安全Rust中为垃圾收集语言编写虚拟机的方法开发的,但可能还有更多用途。
当前状态和待办事项
目前,这些包处于WIP和实验性状态,但基本上可使用且安全。一些值得注意的当前限制
-
虽然这些包希望没有病理性的缓慢,但目前并未高度优化。在
gc-arena
包中的垃圾收集器是一个基本的增量标记-清除收集器,本身并不太糟糕,但每个分配的空间开销仍然很大。此外,目前还没有在Gc指针中分配DST的方法,这需要为任何非Sized
类型进行非常缓慢的双重间接。这两个问题都是可以解决的,但目前还没有完成这项工作。 -
目前没有对象终结系统。这根据系统而异,并不特别困难,但需要选择特定的边缘情况终结行为。
-
缺少很多
Sequence
组合子,并且目前没有方便构建循环Sequence
的方法。这很容易解决,但目前尚未完成。 -
一个更难解决的问题是目前还没有多线程分配和收集的系统。在这里的基本生命周期和安全技术,在支持多线程的领域中仍然有效,但这些存储库不支持这一点。
-
另一个限制是,
Collect
特质没有提供在对象分配后移动对象的方法,这限制了可以编写的收集器的类型。 -
gc-sequence
存储库的使用不方便,因为它需要组合子来构建Sequence
。在Rust生成器的帮助下,这可以大大简化,但是仍然存在一个限制,即生成器不会自动实现Collect
。因此,即使有了生成器支持,也仍然需要避免在生成器内部保留垃圾收集值,这限制了它们的有用性。如果将来有可能通过一些尚未设计的Rust特性自动在生成器上实现Collect
,这将极大地提高这些存储库中技术的一般便利性和可行性。 -
这些存储库目前缺乏文档和示例。
现有技术
这里的想法大多不是我的,大部分设计是从rust-gc那里借鉴的,使用“生成性”的想法来自You can't spell trust without Rust,而大多数Sequence
设计是直接从futures-rs那里借鉴的。
许可
这个存储库中的所有内容都受以下任一许可的许可:
- MIT许可 LICENSE-MIT 或 http://opensource.org/licenses/MIT
- 创意共享CC0 1.0通用公共领域奉献 LICENSE-CC0 或 https://creativecommons.org/publicdomain/zero/1.0/
由您选择。
依赖关系
~1.5MB
~37K SLoC