Erlang中的垃圾收集和内存管理

时间:2012-04-19 05:00:19

标签: memory-management garbage-collection erlang

我想知道Erlang中垃圾收集和内存管理的技术细节。

但是,我在Erlang.org及其文档中找不到它。

网上的一些文章只是一般的谈话而没有触及细节,例如使用什么垃圾收集算法,什么是性能开销,内存分配也像C中的堆?

有人可以推荐更好的文档来学习吗?

谢谢

4 个答案:

答案 0 :(得分:15)

该算法的参考文件:One Pass Real-Time Generational Mark-Sweep Garbage Collection (1995)由Joe Armstrong和Robert Virding于1995年(在CiteSeerX上)

答案 1 :(得分:14)

要对事物进行分类,请定义内存布局,然后讨论GC的工作原理。

内存布局

在Erlang中,每个执行线程称为一个进程。每个流程都有自己的内存,内存布局由三部分组成:流程控制块堆栈

enter image description here

  • PCB:过程控制块保存过程标识符(PID),当前状态(运行,等待),其注册名称和其他此类信息等信息。

  • 堆栈:这是一个向下增长的内存区域,它保存传入和传出参数,返回地址,局部变量和用于计算表达式的临时空间。

  • 堆:这是一个向上增长的内存区域,用于保存进程邮箱消息和复合术语。大于64字节的二进制项是 NOT 存储在进程专用堆中。它们存储在大型共享堆中,可供所有进程访问。

垃圾收集

目前,Erlang使用 Generational 垃圾收集,它独立地在每个Erlang进程私有堆内运行,并且还为全局共享堆发生引用计数垃圾收集。

  • 私有GC GC:它是世代的,因此将堆分为两个部分:年轻代和旧代。还有两种收集策略;分代(轻微)和全程(重大)。世代GC只收集年轻的堆,但是全面收集年轻和旧堆。

  • 共享堆GC:这是引用计数。共享堆中的每个对象(Refc)都有一个对其持有的引用计数器,其他对象(ProcBin)存储在Erlang进程的私有堆中。如果对象的引用计数器达到零,则该对象将无法访问并将被销毁。

要获得更多详细信息和效果提示,请查看我的文章,这是答案的来源:Erlang Garbage Collection Details and Why It Matters

答案 2 :(得分:12)

Erlang有一些属性让GC非常容易。

1 - 每个变量都是不可变的,因此变量永远不会指向在它之后创建的值。

2 - 在Erlang进程之间复制值,因此进程中引用的内存几乎总是完全隔离。

这两者(特别是后者)显着限制了GC在收集过程中必须扫描的堆量。

Erlang使用复制GC。在GC期间,该过程停止,然后将实时指针从空间复制到空间。我忘记了确切的百分比,但是如果在集合期间只能收集25%的堆,那么堆将会增加,如果可以收集75%的进程堆,它将会减少。当进程堆已满时触发集合。

唯一的例外是发送到另一个进程的大值。这些将被复制到共享空间并被引用计数。当收集对共享对象的引用时,计数减少,当该计数为0时,对象被释放。没有尝试处理共享堆中的碎片。

这样做的一个有趣结果是,对于共享对象,共享对象的大小不会影响进程堆的计算大小,只会影响引用的大小。这意味着,如果您有大量大型共享对象,则在触发GC之前,您的VM可能会耗尽内存。

大多数情况下,如果这是从Jesper Wilhelmsson在EUC2012上发表的演讲中获得的。

答案 3 :(得分:2)

我不知道你的背景,但除了jj1bdx已经指出的论文之外,你还可以给Jesper Wilhelmsson thesis一个机会。

BTW,如果你想监视Erlang中的内存使用情况,将它与例如Erlang进行比较。您可以查看C ++:

希望这有帮助!