【问题标题】:How can I replace this call to GC.Collect?如何替换对 GC.Collect 的调用?
【发布时间】:2012-07-29 18:05:37
【问题描述】:

我有一个应用程序,它在伪代码中工作如下:

DisplayPrettyUI()
DoABunchOfReportingWorkThatAllocatesHundredsOfMB()
GC.Collect() //Free up the memory used in generating the report
DisplayReport()

现在,我无法完全摆脱 collect 调用,因为如果我这样做了,那么在生成报告后该进程会保留超过 GB 的内存,尽管应用程序仅托管 UI 组件来显示当时报告。同时,对 Collect 的调用似乎很“臭”;而且似乎必须有某种方法可以在不去那里的情况下处理这种情况。

可以去除这种气味吗? (我听说过像 AppDomain 之类的东西来解决这个问题,但我以前从未使用过 AppDomain,也不知道它对垃圾收集器有什么语义......)

【问题讨论】:

  • 这听起来像是对GC.Collect的合法使用。
  • 尝试优化 DoABunchOfReportingWorkThatAllocatesHundredsOfMB() 显然但除此之外没有很多其他选项
  • @EOG:这没有任何意义。 UI 中没有对报告基础架构数据的引用。垃圾收集器没有运行,因为这台机器有 12GB 的 RAM,因此它认为没有足够的内存压力来运行。空变量比无用更糟糕。
  • 如果机器有12GB内存并且没有释放内存的压力,那你为什么觉得需要手动运行GC?
  • 简单的家伙。你没有量化性能问题,所以我怎么知道重写是否有点激烈?

标签: c# .net garbage-collection clr appdomain


【解决方案1】:

您可以使用 Optimized 的 GCColletionMode 标志调用 GC.Collection,因此此时不一定会强制垃圾回收......如果没有必要,GC 可以延迟它。

另外看看AddMemoryPressure,这里有一些想法:

【讨论】:

    【解决方案2】:

    我们通常解决此问题的方法是将报告拆分为单独的线程甚至物理进程,具体取决于我们使用的工具。

    有些第三方报告工具是绝对的资源消耗者,当它们崩溃时往往会导致整个应用程序崩溃。将它们分离到自己的进程中可以隔离潜在的损害,并允许我们实例化足以使我们保持在资源限制之下,但仍能响应用户请求。

    话虽如此,如果这不适合您的应用程序,我认为在您的情况下使用 Collect 没有任何问题。

    【讨论】:

    • 嗯……AppDomain 不是 .NET 领域的“进程”吗?
    • 是的,但我们发现由于一些第三方工具是基于 COM 的,因此使用独立进程是最安全和最干净的。
    • 那么 appdomain 有它自己的垃圾收集器“实例”吗?
    • 没有。有关详细信息,请参阅此 SO 帖子:stackoverflow.com/questions/2723579/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2015-12-20
    • 1970-01-01
    • 2011-07-15
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多