为什么刷怪会打副本?

Why will spawning make a copy?

每当我使用 spawn(Mod, Func, Arguments) 时,所有参数都会被复制。如果在 Erlang 中一切都是不可变的,为什么要复制它们?为什么不只复制指针?是不是因为这让垃圾收集变得更加复杂?

目前,Erlang VM 维护着一个 separate heap per process*。这意味着一个进程可以独立于其他进程收集它的垃圾,使 Erlang 比保持全局堆的运行时更不容易受到 GC 暂停的影响。

为了使其有效,必须没有进程引用在另一个进程的堆上分配的内存。 据推测,复制发送到 spawn/3 的参数的原因是为了将它们移动到新生成的进程的堆中。顺便说一句,发送到进程的消息也是如此(来源:参见上面的 link):

All data in messages between Erlang processes is copied, with the exception of refc binaries on the same Erlang node.

(*) 您可能喜欢阅读 this blog post 关于 Erlang 中的垃圾收集的内容。它实际上比我一开始说的要复杂一些,因为一些对象(特别是原子和大型双星)是分开处理的。

Robert Virding 在下面的评论中添加了以下内容:

Having separate heaps for each process make the GC simpler and more efficient, you can reclaim much more memory in each pass than with a real-time collector. Also it scales much better in a parallel system as there are much much fewer locks and less synchronisation, which kills speed. It can also give better locality of memory and cache performance. It's one of those things which sounds worse but ends up being better.