2010-04-06 31 views
27

我阅读了.NET框架4目前的垃圾收集实现替换:背景和并发垃圾收集的区别?

.NET Framework 4中提供 后台垃圾收集。这个 功能替代了先前版本中的并发垃圾 集合,并且 提供了更好的性能。

this page有一个解释它是如何工作的,但我不知道我是否理解它。

在实际应用中,这种新的GC实现有什么好处?它是否可以用于推动从3.5或以前到4.0的转换?

回答

75

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

基本的GC使用“停止世界”策略:应用程序线程从共同的堆中分配内存块。 GC必须运行时(例如分配的块太多,需要进行一些清理),全部应用(管理)线程停止。最后一个停止的线程运行GC,并在完成时释放所有其他线程。世界停止的GC很容易实现,但会导致在用户级别可以察觉的暂停。

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

并发GC有一些限制。也就是说,有些时候GC线程必须对堆进行一定的排他控制。在这种情况下,应用程序线程只能从小的线程特定区域分配块。具有较大需求的线程很快就会碰到主堆,当时它被GC线程锁定。然后,分配线程必须阻塞,直到GC线程完成其锁相阶段。这再次诱发暂停。与停止世界的GC相比,停顿时间更短,并且这些暂停不会影响所有线程。然而,暂停。

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

注意:有并发GC和背景GC的“隐藏成本”。为了使这些GC正常工作,应用线程的内存访问必须以一些非常特定的方式完成,这对性能有轻微的影响。此外,GC线程可能会对高速缓存造成不利影响,从而间接降低性能。对于不需要用户交互的纯粹计算任务而言,世界平台收集器平均可以产生更好的性能(例如,20小时的计算将在19个小时内完成)。但这是一个边缘案例,在大多数情况下,并发GC和后台GC都更好。

+0

很好的解释..但是如果你坚持使用主流的术语,它会更合适。托管线程/代码等适用?那是什么? – 2012-11-27 21:31:49

+8

应用程序线程是运行程序员编写的代码的线程(与隐藏管理线程相反,如果有的话)。 “管理”线程是运行托管代码的线程(即不是用C或C++编写的代码)。这是_is_主流术语。 – 2012-11-27 23:28:49

1

由于垃圾收集,最主要的好处将是减少应用程序冻结,这本身可以被认为是一个重大的改进。对于大多数应用程序来说,除非内存中有大量的长寿命对象,否则这种差异不会显而易见。

这个改变也让.NET在构建对时间敏感的应用程序(响应时间很重要)方面稍微更可行。极端的例子是汽车安全气囊 - 您不希望软件在需要充气时忙于垃圾收集。 4.0中的更改减少了由GCing引起的冻结数量和长度,但不会完全删除它们。

8

这里是没有污点和重视自我过度膨胀的感觉,现实世界的解释:

在并行GC,你被允许在GC分配时间,但你允许启动另一个GC而在GC中。这又意味着您在GC中允许分配的最大空间是您在一个区段(当前工作站模式下为16 MB)上剩余的任何空间减去已在那里分配的任何空间。

在后台模式不同的是,你允许开始新的GC(根0 + 1),而在一个完整的背景GC,这甚至允许你创建一个新的细分市场如果分配在必要。简而言之,在您将所有内容分配给一个分段之前可能发生的阻塞现象不会再发生。

从苔丝达曼! http://blogs.msdn.com/b/tess/archive/2009/05/29/background-garbage-collection-in-clr-4-0.aspx