copy on write
swift 中的 cow
swift 中有 struct 和 class 这两种数据结构,很多入门教程都会介绍说,struct 和 class 最大的区别是,struct 是值类型,而 class 是引用类型。换句话说,struct 在传递的过程中是值传递,而 class 传的则是引用。那么为什么需要这两种传值机制呢?
- 从并发角度看,值传递似乎是一种更安全的选择。因为值传递在每次传递过程中,对象都会被拷贝一份,这样可以防止对象被意外修改。
- 但是在很多情况下,或许用户确实需要一个对象在不同的执行块共享,甚至共同修改,这时候引用传递显然更适合。
- 更重要的是,引用传递是一种开销更小的传递方式,程序不需要为这次传递申请一块新的内存并拷贝对象,也不用考虑对象失去全部有效引用时回收这块新开辟的内存。
那有没有可能实现一种技术,让我们同时享受值传递和引用传递的优点呢?答案是”写时复制”(cow, copy-on-write)。顾名思义,cow 就是说当使用值传递的时候,在新的代码块中依旧引用原来的对象,直到改变(写)对象的时候,才复制一份对象并引用新对象。在 swift 中,你可以使用 mutating 关键字来标识 struct 的某个方法是否会改变这个对象。当调用一个 mutating 方法时,才会真的复制一份对象。
cow 与引用计数
英文好的同学建议直接读这篇 instagram 的原文 「在 instagram 停用了 python 的垃圾回收」。
linux 内核有一个这样的机制:子进程启动时会共享父进程的内存页,但是只有当子进程试图去写这些内存页的时候,才会把这些内存拷贝到新的内存页,也就是我们说的”写时复制”。但是在 python 中,由于 python 使用引用计数来进行垃圾回收,这导致了每次读一个对象,都需要去写这个对象的引用数(加 1),所以所有的读就都变成了写,cow 机制就失效了。为此,instagram 关掉了 python 的 gc…