用 Rust 编写解释器:关于垃圾回收

这是一个关于用 Rust 实现 Lox 编程语言的垃圾回收(GC)的项目总结:

  • 项目背景:几年前对实现编程语言感兴趣,使用 Rust 遵循《Crafting Interpreters》,实现了支持 Lox 语言所有特性的字节码解释器,但存在内存泄漏问题,现在重新审视并改进内存管理方案。
  • 目标:实现与 C 实现相当的标记-清除(mark-and-sweep)GC,过程中会使用较多unsafe语句。
  • 管理内存:定义了垃圾和 GC 的作用,软件需在计算机内存(RAM)中存储数据,Lox 是托管高级语言,VM 会自动处理堆内存的分配和回收,GC 组件负责此操作。
  • 垃圾收集:GC 的重要任务是确定不再使用的数据,Lox 中的对象通过引用传递,GC 采用标记-清除算法,分为标记和清除两个阶段,确定可达对象和不可达对象。
  • 语言差异:Rust 中变量有三种类型,遵循借用检查器规则,而 Lox 语义中对象通过引用传递,无共享或独占之分,两者在处理对象上存在差异,严格遵循 Rust 借用检查器规则时,无法实现两个变量修改同一内存地址。
  • 解决方法

    • 引用计数:利用 Rust 的Rc<T>RefCell<T>实现共享可变引用,但要注意避免创建循环引用,Lox 允许循环引用,此方法单独使用不安全。
    • 对象管理器:通过对象管理器显式建模 Lox 的堆,对象持有堆中数据的索引,避免直接使用内存指针,但存在性能问题,且不能将内存返回给操作系统。
    • 不安全实现:仿照原始 C 实现定义结构,使用NonNull<T>等,通过unsafe实现一些操作,虽有风险但在 VM 内可保证安全性。
  • 后续思考:可以利用 Rust 的类型系统证明 GC 的安全性,如使用Pin<T>等,还有很多在 Rust 中提供 GC 库的发展,如相关文章所述。最后感谢阅读,可查看项目仓库和旧的 GC 实现仓库
阅读 47
0 条评论