【问题标题】:Functional languages with concurrent garbage collectors?具有并发垃圾收集器的功能语言?
【发布时间】:2008-11-10 13:02:56
【问题描述】:

Microsoft 的新 F# 编程语言将函数式编程(一流的词法闭包和尾部调用)与高效的并发垃圾收集器相结合,从而轻松利用多核。

OCaml、Haskell、Erlang 以及我所知道的所有免费 Lisp 和 Scheme 实现都没有并发 GC。 Scala 和 Clojure 有并发 GC,但没有尾调用。

因此,似乎没有结合这些功能的开源编程语言。对吗?

【问题讨论】:

  • 请注意,根据blogs.msdn.com/clyon/archive/2004/09/08/226981.aspx,MS 的并发 GC 是单线程的(非并行的)。他们确实提供了一个并行 GC(“服务器 GC”),它不是并发的,但他们声称比并发 GC 具有更高的吞吐量。
  • 请注意,您引用的博文来自 2004 年,并且 .NET GC 在 .NET 3.5 SP1 中已被新的“后台 GC”所取代。

标签: garbage-collection concurrency tail-call


【解决方案1】:

Erlang 有一个无共享模型,其中each process has it's own garbage collector。您是否认为这不是并发,这取决于您。但随着进程数量的增加,它肯定可以很好地扩展。

【讨论】:

  • Erlang 如何处理从一个进程传递到另一个进程的数据?是否在每次传输时复制?
  • 一般来说是的,因为 Erlang 支持无缝分发。一个实现可能会在后台进程之间共享内存,但我认为现有的任何实现都不会。
【解决方案2】:

最新版本的 GHC 支持并行 GC。请参阅release notes

【讨论】:

  • 我也会注意到这一点,但并行和并发垃圾收集不是一回事。
  • 确实如此。这就是 Haskell 的 GC 无法扩展的原因。
  • 错误...这取决于您要扩展的内容。正如我上面所指出的,MS 实际上提供了一种非并发 GC,因为它的扩展性(在吞吐量方面)比并发的更好。
  • @Curt:扩展和吞吐量不是一回事。 .NET 的非并发并行“服务器”GC 选项会牺牲延迟来提高吞吐量。如果您为每个内核运行一个线程的程序,其中只有一个线程进行大量分配,那么您会发现服务器 GC 的扩展性比默认的并发 GC 差得多,因为一个线程会降低所有其他具有非并发 GC 的线程的性能。 Haskell 和默认的 JVM GC 表现出同样的问题。因此我说 Haskell 的 GC 无法扩展。
  • 如果你生成大量垃圾并且你不关心延迟(假设它是一个运行几个小时的分析程序,你只看最后结果),速度提高的并行 GC(即,您花费更少的挂钟时间进行 GC)不是“缩放”。当您为 GC 提供更多内核时,程序是否运行得更快(在挂钟时间内)?
【解决方案3】:

Scala 有一些尾递归优化。但是请获取SISC scheme 以获得完整信息。

【讨论】:

    【解决方案4】:

    不是您问题的真正答案,但据我所知,F# 使用标准的 .NET 垃圾收集器,它不是并发的; GC 期间所有线程都停止。

    编辑:我的错误,在多处理器模式下存在并发 GC。

    【讨论】:

    【解决方案5】:

    据说Java 正在添加尾调用。当这种情况发生时,clojure 会得到它们。同时,您可以使用循环/递归机制手动获取它们。

    【讨论】:

    • loop/recur 会让你获得尾 recursion(对自身的尾调用),但不是一般的尾调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2011-10-29
    • 2011-09-05
    • 2018-12-30
    相关资源
    最近更新 更多