Haskell中的垃圾收集&并行计算

时间:2012-03-03 16:36:46

标签: haskell parallel-processing garbage-collection immutability

大多数使用垃圾收集器(可能都是所有语言)的语言都有一个与并行计算相关的主要问题:垃圾收集器必须停止所有正在运行的线程才能删除未使用的对象。 Haskell也有垃圾收集器。但是,由于纯度,Haskell保证没有计算改变原始数据,而是生成副本,然后进行更改。我想,通过这种方式,GC不必停止所有线程来完成它的工作。我只是好奇:Haskell是否与垃圾收集有相同的问题?

2 个答案:

答案 0 :(得分:17)

GHC的垃圾收集器并行但不是并发。这意味着它可以使用所有线程来执行垃圾收集,但它必须阻止所有线程执行此操作。并发垃圾收集更难实现(并且通常具有更大的性能开销)。

Haskell确实使用了许多可变对象,即thunk(未评估的表达式),这有点讽刺。可变对象不能自由复制(即使对于不可变对象,也应该检查过多的复制)。

对于在具有真正并发收集器的多个内核上运行的程序会很不错,但是通过执行 heap-local 垃圾收集也可以获得不错的好处。这个想法是,多个CPU之间不共享的数据只能由拥有的CPU收集。这通常是短期数据的情况。西蒙斯最近在这方面做了一些工作。见他们的论文"Multicore Garbage Collection with Local Heaps" (PDF)。本文还介绍了一些如何以类似于您提议的方式利用不变性的方法。

编辑:我忘了提到Erlang基本上完全按照你的建议行事。每个Erlang进程都有自己的堆,并且发送消息将数据从一个进程复制到另一个进程。因此,每个Erlang进程都可以独立于所有其他进程执行自己的GC。 (缺点是Erlang不会给你共享内存并发。)

答案 1 :(得分:1)

Seval GC实现可以并行运行而不会像你建议的那样“停止世界”(我认为最新的Oracle JVM不会停止世界并且是多线程的,例如;大多数JVM都不是“停止 - -world“)。

回想一下,从一种语言实现到另一种语言实现,GC实现可能有很大差异。

有很多关于GC的文章,还有很多关于并行垃圾收集的研究论文。

从一本好书开始,如the GC handbook(由Richard Jones,Antony Hosking,Eliot Moss撰写)。或者至少是维基百科Garbage Collection页面。

像Haskell这样的纯函数式语言在很大程度上依赖于高性能的GC。其他语言有不同的约束(例如,写入障碍对Haskell的影响小于Java,但Haskell程序可能比Java分配更多)。

对于并行GC,魔鬼非常关注细节。