后台和并发垃圾收集之间的区别?

时间:2010-04-06 08:57:24

标签: garbage-collection .net-4.0

我在.NET Framework 4中读到了当前的垃圾收集实现:

  

.NET Framework 4提供   背景垃圾收集。这个   功能替换并发垃圾   以前版本中的集合和   提供更好的性能。

this page有一个解释它是如何工作的,但我不确定我是否明白。

在实际的世界应用中,这种新GC实施的好处是什么?它是否可用于推动从3.5或之前的过渡到4.0?

3 个答案:

答案 0 :(得分:80)

在这里,Microsoft使用名称“concurrent”和“background”来描述它在.NET中使用的两个版本的GC。在.NET世界中,“后台收集器”是对“并发收集器”的增强,因为它对收集器运行时应用程序线程可以执行的操作的限制较少。

基本GC使用“stop-the-world”策略:applicative threads从公共堆分配内存块。当GC必须运行时(例如,分配了太多的块,需要进行一些清理),所有应用(托管)线程都会停止。最后一个停止线程运行GC,并在完成后取消阻塞所有其他线程。一个停止世界的GC很容易实现,但会导致暂停,这可以在用户级别感知。

微软的“并发GC”是世代的:它只对堆的有限部分使用stop-the-world策略(他们称之为“第0代和第1代”)。由于该部分仍然很小,暂停仍然很短(例如低于50ms),因此用户不会注意到它们。使用专用的GC线程收集堆的其余部分,该线程可以与应用程序线程(因此名称)同时运行

并发GC有一些限制。也就是说,有时候GC线程必须对堆进行一定程度的独占控制。在此期间,应用程序线程可以仅从小线程特定区域分配块。需求较大的线程很快会偶然发现主堆,当时主堆由GC线程锁定。然后必须阻塞分配线程,直到GC线程完成其锁定堆阶段。这再次导致暂停。与停止世界的GC相比,暂停次数减少,这些暂停不会影响所有线程。然而,停顿了一下。

“后台GC”是一个增强型GC,其中GC线程无需锁定堆。这消除了前一段中描述的额外暂停;收集年轻一代时(微软称之为“前景集合”),只能保持有限的停顿。

注意:并发GC和后台GC存在“隐藏成本”。为了使这些GC正常运行,必须以一些非常具体的方式对应用程序线程进行内存访问,这会对性能产生轻微影响。此外,GC线程可能会对高速缓存存储器产生负面影响,从而间接降低性能。对于不需要用户交互的纯粹计算任务,一个世界上的收藏家可能平均,产生更好的性能(例如,一个二十小时的计算将在十九小时内完成) 。但这是一个边缘情况,在大多数情况下,并发和后台GC更好。

答案 1 :(得分:8)

这是现实世界的解释,没有诽谤和过度膨胀的自我感觉:

  

在并发GC中,您可以在GC中进行分配,但是您 允许在GC中启动另一个GC。这反过来意味着在GC中允许分配的最大值是在一个段上留下的任何空间(当前在工作站模式下为16 MB)减去已在那里分配的任何内容。 / p>      

背景模式的不同之处在于,在完整的后台GC中,允许启动新的GC(gen 0 + 1),而允许您甚至创建一个新的细分以在必要时分配。简而言之,在您在一个段中分配所有内容之前可能发生的阻塞将不再发生。

来自Tess da Man! http://blogs.msdn.com/b/tess/archive/2009/05/29/background-garbage-collection-in-clr-4-0.aspx

答案 2 :(得分:1)

主要的好处是由于垃圾收集导致的应用冻结减少,这本身可以被视为一项重大改进。对于大多数应用程序而言,除非您在内存中有大量长寿命对象,否则这种差异不会引人注意。

此更改还使.NET更适合构建对时间敏感的应用程序(响应时间非常重要)。极端的例子是汽车安全气囊 - 你不希望你的软件在需要充气时忙于垃圾收集。 4.0中的更改减少了因GCing而导致冻结的次数和长度,但未完全删除它们。