午夜咖啡午夜咖啡

jolestar 的文章与笔记。

Post

Rust 和垃圾回收的差异,不只是性能,而是谁真正控制系统资源

2021-06-01 09:07:42Post

垃圾回收带来的不只是自动内存管理,它同时也重新分配了程序员和运行时之间的控制权;Rust 的价值,很大一部分就在于把这层控制权拿回来。

原来写过一篇垃圾回收的微博(http://t.cn/ExTjwU3),今天说说 Rust 和垃圾回收。

垃圾回收机制解放了程序员,但它也带来了问题。就比如本来是你请了一个阿姨打扫卫生,结果她接管了整个屋子的控制权,需要空间啥的都要和她申请,最后你发现好像屋子变成她的了,你只是个客人。在垃圾回收系统上的写程序就是这个感觉。

那怎么办呢?回归传统,自我管理,谁制造谁回收?这个是不可能了,人已经习惯了自动化,何况这个要求所有人都有自我管理能力,只要有一个人偷懒或者忘了,屋子就成垃圾场了,这不太现实。于是 Rust 探索了另外一条路径。

我们先分析一下需要垃圾回收的场景:

如果使用的物品都是一次性的(编程术语来说就是在栈上的变量),用完即丢,实际上不需要专门的垃圾回收机制,每个人下班的时候把自己的垃圾带走就行。

如果同一个物品需要在两个人之间共享,只要能保证第一个人用完了就转移给另外一个人,最后一个人用完了丢掉,就简化成上面的场景了。很多函数式编程就是这样做的。

只有同一个物品,多个人一起用的时候才容易产生垃圾和错误,如果一个人提前收走了,另外要用的人就会出错(空指针错误),如果都忘记扔了,就会产生垃圾堆积(内存泄漏)。

那我们能不能设计好一些规则,让大家都遵循这样的规则来使用物品,是不是就可以简化这个问题?

  1. 物品的所有权要明确。拥有所有权的人需要负责物品的生命周期,别人用时候是借用还是转让,要说明清楚(这个就是 Rust 里的 move 关键词的作用)。
  2. 借用物品要说明借用的周期。比如你要加班,但同事要按时下班,你就不能借用 TA 的东西,周期不匹配,所有者的周期要大于借用者。(这就是 Rust 中的引用需要生命周期参数的原因)
  3. 周期不匹配带来的问题很麻烦,那怎么办?把物品所有权转让给一个机器人托管,机器人记个数,当物品没有任何人借用后,机器人回收掉这个物品。机制上虽然和垃圾回收有点像,但这个是针对具体的物品,逻辑简单多了。(这就是 Rust 中的 rc/arc 的作用)

这样理解,Rust 是不是也没那么复杂了?通过以上的规则,Rust 实现了既不需要运行时的垃圾回收,也不需要程序员显式的释放资源。如果代码不符合上面的规则,编译器直接会报错。虽然编译器有时候还比较笨拙,但用熟了就能有“从心所欲不逾矩”的感觉,并且对程序有一种完全的掌控感。

ps: 求对区块链底层研发感兴趣的 Rust 高手或者想转 Rust 的高手加盟。