erlang内存模型:私有堆 vs 共享堆
翻译 by 吹牛逼翻译小组
原文:Erlang Memory models: Private Heap vs Shared Heap
在程序语言中支持并发被称为并发模型。我对java并发模型有一些经验,但是最近我读到其它程序语言的革命性的内存模型,这个语言就是erlang。
erlang是一个并发,具有垃圾回收和运行时系统的函数式编程语言。erlang被Ericsson在1986设计并在1998作为一个开源项目发布。现在它在互联网软件公司中获得越来越多的关注,对此我一点也不惊讶。
java的基础并发模型是同步共享数据结构(内存分享模型),在这种情况下并发改变需要同步锁保护共享的对象。
为了代替共享数据结构模型,erlang使用一种叫做消息传递的技术(消息交换模型)。高效的并发消息传递需要一个特别的内存架构。以下,我将快速的介绍这两种不同的方式。
私有堆架构
到2001,Ericsson在Erlang/OTP R8 中实现的唯一的内存架构是每一个进程分配并且管理它自己的内存区域。在这种情况下,每一个进程分配并且管理它自己的私有内存区域,利用:PCB,私有栈和私有堆。在这种架构下,消息传递通过从发送者的堆复制消息到接受者的堆,并插入一个指针到接受者的消息队列(也叫信箱)。
优点:容易并且高效的垃圾回收。提高缓存利用。
缺点:昂贵的消息传递。需要更多的空间。
共享堆架构
在私有堆架构下,发送一个消息到另外一个进程,通过复制消息数据到接受者的堆。这是一个O(n)操作,n是消息的大小。这个问题能够被共享堆避免。每一个进程任然有自己的栈,但是所有的进程共享一个全局堆。这个架构容易进程通信,事实上,这种情况下发送一个消息仅仅需要复制消息的引用到接受者的信箱。这种方式下消息传递花费常量时间。
优点:快速的消息传递。需要更少的空间。
缺点:垃圾回收有很大的根集并且需要更多的垃圾回收时间。
混合架构
我们已经看到每一种内存架构有着自己的优点。私有堆系统允许快速的,便宜的回收内存。同时,共享堆系统对进程通信有着优化。这个混合解决方案尝试(已经失败了)组合这两种优点。在这种解决方案下,每一个进程有自己的用于局部数据的堆。并增加了一个全局共享堆。在这个堆中存放着消息数据。为了使垃圾回收高效,这个架构禁止任何共享堆的指针指向私有堆。
优点:高速的消息传递。需要少的空间。高效的本地垃圾回收。
缺点:垃圾回收区域任然有很大的回收根集。必须在编译时间知道数据是局部数据还是作为消息。
这两种架构:私有堆和共享堆,已经在Erlang/OTP R8中实现并发布并且用户能够通过配置选项自主选择。第三种架构,混合架构,不幸的是,因为过多的锁和垃圾回收缓慢并且难以维护,已被丢弃。
深度阅读:
A thesis on this argument where I found the information for this post.