9

我知道停止世界、增量、并行、并发、(软/硬)实时垃圾收集器的概念。但我无法理解主要是并发GC。与并发 GC 有什么不同吗?有什么不同?为什么它被称为主要

4

2 回答 2

7

我知道停止世界、增量、并行、并发、(软/硬)实时垃圾收集器的概念。但我无法理解主要是并发 GC。与并发 GC 有什么不同吗?有什么不同?为什么它被称为主要?

像许多其他主题一样,垃圾收集被笼罩在术语模糊的迷雾中。Boehm 因以非传统方式使用传统术语而特别臭名昭著,但我们应该原谅他,因为他在传统含义尚未固化的时候开创了该领域!:-)

据我了解,stop-the-world GC 是指一种算法,它在 GC 周期的整个持续时间内(例如在标记整个堆时)暂停所有 mutator 线程。例如,.NET Server GC 执行此操作并因此导致 300 毫秒的巨大暂停时间。增量 GC 在每个次要 GC 周期执行一些主要 GC 工作,例如 OCaml GC 中的“主要切片”。并行意味着 GC 使用多个线程来加速收集垃圾的过程。并发 GC 意味着 GC 与 mutators 同时运行,例如 .NET 工作站 GC。Real-time 很难定义,最初是指有界的最大暂停时间,但现在也意味着最小 mutator 利用率(MMU),以避免 GC 的病态问题,即永远不会让 mutator 运行而长时间暂停它!根据理查德琼斯的新书,尽管我怀疑他的意思是突变器彼此独立地暂停,但即时 GC 一次不会暂停多个突变器(即没有停止世界阶段)。最后,大多数并发 GC 是一种同时挂起所有 mutator 线程但仅在短时间内而不是任意长的 GC 周期的GC。因此,在 GC 运行时,mutators 大部分时间都可以自由运行,因此,它被称为“大部分并发”GC。大多数并发 GC 是一种同时挂起所有 mutator 线程但仅在短时间内而不是在任意长的 GC 周期内挂起的 GC。因此,在 GC 运行时,mutators 大部分时间都可以自由运行,因此,它被称为“大部分并发”GC。大多数并发 GC 是一种同时挂起所有 mutator 线程但仅在短时间内而不是在任意长的 GC 周期内挂起的 GC。因此,在 GC 运行时,mutators 大部分时间都可以自由运行,因此,它被称为“大部分并发”GC。

“大部分并发”的分类很重要,因为大多数(所有?)主要 GC 都属于这一类,因为它在暂停时间和吞吐量之间提供了良好的权衡。例如,.NET 工作站 GC 在拍摄全局根的快照时暂停所有 mutator 线程,但在标记和扫描时恢复它们。

于 2011-11-01T16:47:02.690 回答
2

您可以在 Bohem、Demers 和 Shenker 的论文“Mostly Parallel Garbage Collection”中找到易于理解的描述(ACM SIGPLAN '91 编程语言设计和实现会议论文集,SIGPLAN Notices 26, 6 (June 1991), pp. 157-164)。

他们写:

假设我们能够维护一组虚拟脏位,每当写入相应的虚拟内存页面时就会自动设置这些位。(此功能的可接受实现可以通过写保护页面并捕获产生的写错误来获得,而不需要对底层 OS 内核进行修改;OS 内核中的实现当然会更有效。)对于定义的任何跟踪收集器对于 stop-the-world 操作,请考虑以下收集算法。在收集开始时,清除所有虚拟脏位。与 mutator 并行执行传统的跟踪操作。将更新虚拟脏位以反映 mutator 写入。跟踪完成后,停止世界并跟踪位于脏页上的所有标记对象。

...

在该算法中,并行跟踪阶段提供了对真实可达集的近似。该并行跟踪过程未标记且确实可到达的唯一对象必须可从自跟踪后已写入的标记对象中到达。stop-the-world 跟踪阶段跟踪所有此类对象,因此最终没有真正可到达的对象未被标记。

当他们提到跟踪垃圾收集器时,他们指的是从指定的“根节点”(通常是程序的寄存器)开始并跟随指向每个可访问对象的指针的收集器。一切达不到的都是垃圾。

简而言之,大部分并行的收集器并行完成大部分工作,然后停止程序的执行以纠正程序在收集器运行时所做的任何更改。因此,它“大部分是平行的”。

于 2011-10-13T05:01:46.167 回答