【问题标题】:What is the advantage of runtime GC over compile-time ARC?运行时 GC 与编译时 ARC 相比有什么优势?
【发布时间】:2015-09-09 04:16:10
【问题描述】:

一些较新的语言正在将 ARC 实现到它们的编译器中(Swift 和 Rust,仅举几例)。据我了解,这实现了与运行时 GC 相同的效果(将手动释放的负担从程序员身上移开),同时效率显着提高。

我知道 ARC 可能会成为一个复杂的过程,但随着现代垃圾收集器的复杂性,实现 ARC 似乎不再复杂。但是,仍然有大量的语言和框架使用 GC 进行内存管理,甚至以系统编程为目标的 Go 语言也使用 GC。

我真的不明白为什么 GC 比 ARC 更可取。我在这里遗漏了什么吗?

【问题讨论】:

    标签: memory-leaks garbage-collection automatic-ref-counting


    【解决方案1】:

    这里涉及很多权衡,这是一个复杂的话题。不过,这里是大的:

    GC 专家:

    • 跟踪垃圾收集器可以处理对象图中的循环。自动引用计数将泄漏内存,除非通过删除引用或确定图的哪条边应该是弱的来手动破坏循环。这在引用计数应用的实践中是一个很常见的问题。
    • 跟踪垃圾收集器实际上可以比引用计数更快(在吞吐量方面),通过并发工作、批处理工作、推迟工作以及不弄乱热循环中接触引用计数的缓存。李>
    • 复制收集器可以压缩堆,回收碎片页面以减少占用空间

    ARC 专业人士:

    • 因为当引用计数达到 0 时立即发生对象销毁,所以可以使用对象生命周期来管理非内存资源。使用垃圾回收,生命周期是不确定的,所以这是不安全的。
    • 收集工作通常更加分散,从而导致更短的暂停(如果您释放大量对象子图,仍然可能会暂停)
    • 因为内存是同步收集的,所以不可能通过分配快于清理速度来“超越收集器”。当 VM 分页发挥作用时,这一点尤其重要,因为在某些退化的情况下,GC 线程会遇到已被分页的页面,并且远远落后。
    • 在相关说明中,跟踪垃圾收集器必须遍历整个对象图,这会强制进行不必要的分页(有针对此的缓解措施,例如 https://people.cs.umass.edu/~emery/pubs/f034-hertz.pdf,但并未广泛部署)
    • 如果跟踪垃圾收集器想要达到其全部吞吐量,它们通常需要比引用计数更多的“暂存空间”

    我个人对此的看法是,在大多数情况下,真正重要的仅有两点是:

    • ARC 不收集周期
    • GC 没有确定的生命周期

    我觉得这两个问题都会破坏交易,但如果没有更好的主意,你只需要选择哪个可怕的问题听起来更糟。

    【讨论】:

    • 对于跟踪 GC 与引用计数的一般概念比较,本文“垃圾收集的统一理论”展示了如何将它们视为彼此的严格对偶。对每种方法的各种优化和调整只会让您沿着连接它们的范围移动:cs.virginia.edu/~cs415/reading/bacon-garbage.pdf
    • 哦,是的,我喜欢那篇论文 :D 感谢链接
    • 值得注意的是,如果 RC 有循环检测(Apple 的 ARC 没有),它们只是严格的对偶。循环检测的计算成本可能很大且不一致,因此产生的权衡列表与上面的 ARC 与 GC 列表不同!附:更新论文链接:courses.cs.washington.edu/courses/cse590p/05au/p50-bacon.pdf
    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 2011-09-27
    • 1970-01-01
    • 2010-09-24
    相关资源
    最近更新 更多