代码之家  ›  专栏  ›  技术社区  ›  Drake

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

  •  27
  • Drake  · 技术社区  · 14 年前

    我了解到,使用.NET Framework 4,当前的垃圾收集实现将被替换:

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

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

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

    3 回复  |  直到 10 年前
        1
  •  78
  •   Thomas Pornin    14 年前

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

    基本GC使用“停止世界”策略:应用线程从公共堆分配内存块。当必须运行GC时(例如分配了太多的块,需要进行一些清理)。 全部的 应用(管理)线程停止。最后一个停止线程运行gc,并在完成后解除所有其他线程的阻塞。stop-the-world-gc实现起来很简单,但会导致暂停,这在用户级别上是可以感觉到的。

    微软的“并发GC”是世代相传的:它只在堆的有限部分使用停止世界策略(他们称之为“0代和1代”)。由于该部分仍然很小,停顿时间很短(例如低于50毫秒),因此用户不会注意到它们。堆的其余部分是用一个可以运行的专用GC线程收集的 同时地 与应用线程(因此名称)。

    并发GC有一些限制。也就是说,有时GC线程必须对堆进行某种程度的独占控制。在这种情况下,应用线程只能分配来自小线程特定区域的块。有更大需求的线程很快就会遇到主堆,此时主堆被GC线程锁定。然后,分配线程必须阻塞,直到GC线程完成对堆阶段的锁定。这又会引起停顿。暂停时间比停止世界GC少,并且这些暂停不会影响所有线程。然而,停顿了一下。

    “background gc”是一个增强的gc,其中gc线程不需要锁定堆。这将删除上一段中描述的额外暂停;仅在收集年轻一代时保持有限的暂停(微软称之为“前台集合”)。

    注: 并发GC和后台GC存在“隐藏成本”。为了使这些GC正常运行,应用线程的内存访问必须以一些非常具体的方式进行,这对性能有轻微的影响。此外,GC线程可能对缓存内存产生不利影响,从而间接降低性能。对于完全不需要用户交互的计算任务,停止WorldCollector可能, 平均 ,产生更好的性能(例如,20小时的计算将在19小时内完成)。但这是一个边缘情况,在大多数情况下,并发GC和后台GC更好。

        2
  •  8
  •   Boppity Bop    12 年前

    下面是现实世界中没有自尊心的轻蔑和过度膨胀的解释:

    在并发GC中,允许您在GC中分配,但是 允许在GC中启动另一个GC。这反过来意味着在GC中允许分配的最大空间是您拥有的任何空间。 左移到一段上 (当前工作站模式下为16 MB)减去已分配的所有空间。

    背景模式的区别在于 被允许 在一个完整的背景GC中启动一个新的GC(gen 0+1),这个 甚至可以创建新段 必要时分配。简而言之,当您在一个段中分配了所有可以分配的数据时,以前可能发生的阻塞将不再发生。

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

        3
  •  1
  •   Morten Mertner    14 年前

    主要的好处是由于垃圾收集而导致的应用程序冻结更少,而垃圾收集本身可以被认为是一个显著的改进。对于大多数应用程序来说,除非在内存中有大量长期存在的对象,否则这种差异是不明显的。

    这种变化也使得.NET在构建时间敏感的应用程序(在响应时间很重要的情况下)时更加可行。最极端的例子是汽车安全气囊——你不希望你的软件在需要充气的时候忙于垃圾收集。4.0中的变化减少了由于GCing而冻结的数量和长度,但并不能完全消除它们。