【问题标题】:Is it more efficient to call the .net Garbage collector?调用 .net 垃圾收集器是否更有效?
【发布时间】:2010-12-21 12:13:17
【问题描述】:

由于在 CLR 中调用垃圾收集器的开销,是离开它更有效,还是在对象超出范围时强制进行垃圾收集?

【问题讨论】:

标签: c# optimization garbage-collection clr performance


【解决方案1】:

大多数时候,手动调用垃圾收集器是不值得的。您会惊讶于底层垃圾收集器算法的效率有多高。

除非您从事的金融应用程序(例如:衍生品交易应用程序)要求您完全控制调用垃圾收集器的时间。但如果你要走这条路,也许你应该尝试其他语言,比如 C++

【讨论】:

  • 为什么金融应用需要这个?
  • 例如,如果您正在交易有非常精确的时间要求的证券,GC 可能会在您不希望的时候对其产生负面影响。
  • 显式调用 GC 并不能保证任何事情。如果您有严格的实时要求,那么正如您在编辑中指出的那样,托管代码可能不适合。但是,如果你真的有实时限制,那么 C++ 也无济于事,除非底层操作系统有延迟保证,而 Windows 没有。
【解决方案2】:

编写 .NET 和垃圾收集器的人对它进行了很多思考,因此您不必这样做。只需在适用时对您的对象调用 dispose 即可,其余的不用担心。

【讨论】:

    【解决方案3】:

    自己调用 GC 的主要原因之一是,由于 GC 是自调整的,因此您从托管堆中收集的任何调用都会有效地破坏任何自调整GC 已代表您的申请完成。

    GC 将做的主要事情之一是调整在托管堆的三代中的每一代上触发垃圾收集的阈值,以减少您的应用程序所需的收集数量。

    对于除极端情况外的所有情况,最好让 GC 完成其工作,而不必担心手动调用它。只有当您确定了明确的需求时,您才应该手动调用集合。

    【讨论】:

      【解决方案4】:

      除了 Andrew 的 cmets,不必要地调用 GC.Collect 会导致其他有效的 Gen-0 收集被推入 Gen-1 和 Gen-2 存储桶,而这些存储桶的收集频率要低得多。具有讽刺意味的是,这意味着您的应用程序将遭受长期内存使用量增加的影响,违背了减少内存使用量的初衷。

      需要调用 GC.Collect 的少数情况之一是与 COM 或 Win32 互操作时。例如,Office 中的 COM 对象停留时间超过预期的情况并不少见,因为无法显式处置它们。因此,您可能希望在特定时间对 COM 包装器进行 GC,然后通常会调用 WaitForPendingFinalizers。

      【讨论】:

      • 当 GC 运行时,它是否只是从 GEN-0 收集,直到它满了然后在 GEN-1 上运行?
      • 它更频繁地执行 Gen-0 收集。我相信它会根据内存压力情况执行 Gen-1 和 Gen-2 收集。这是一篇关于该算法的优秀 MSDN 文章。 msdn.microsoft.com/en-us/magazine/bb985010.aspx
      【解决方案5】:

      由于在 CLR 中调用垃圾收集器的开销,是离开它更有效,还是在对象超出范围时强制进行垃圾收集?

      几乎肯定不用管它会更有效。

      另外,请注意,在源代码中超出范围的对象仅与 GC 收集它们有微弱的关系。你的程序在 GC 与之交互之前经历了许多转换,到那时,范围的概念几乎完全消失了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 2011-03-05
        • 2021-05-25
        相关资源
        最近更新 更多