【问题标题】:Garbage Collection - Mutex垃圾收集 - 互斥锁
【发布时间】:2012-12-03 16:19:08
【问题描述】:

根据我的研究,一般的经验法则是不要乱用 GC(即不要调用 GC.Collect())。我们有一个基于服务器的进程来处理巨大的 XML 文档——内存永远不会被释放。代码如下所示:

while (!abort)
{
  mutex.WaitOne();

  //sets abort to true to end the process itself
  DoSomeWork();

  mutex.ReleaseMutex();
}

DoSomeWork() 运行后,内存永远不会被释放。发生这种情况是因为 GC 没有任何“独处时间”来做它的事情吗?我们应该在 DoSomeWork() 之后调用 GC.Collect 来强制 GC 吗?

谢谢

【问题讨论】:

  • 垃圾收集器通常不会释放内存,直到它觉得可能需要它。如果内存充足,垃圾收集器不会运行。
  • C#,.Net。抱歉 - 应该提到这一点。

标签: c# garbage-collection mutex collect


【解决方案1】:

尝试在开发环境中调用GC.Collect,看看会发生什么。如果内存没有下降,则说明内存泄漏。这可能意味着您没有释放您实际完成的对象,并且在某处有对它们的引用;或者可能是您没有正确处理非托管内存。如果它确实下降,则意味着您只需要给 GC 时间。

如果对象确实符合收集条件(根据之前的测试),请考虑是否必须立即减少内存,或者等待几百毫秒以安排 GC 是否可以接受。您是否收到 OOM 错误?应用程序是否因此被交换到磁盘?如果不是,请考虑等待 GC 执行此操作。

还要问问自己是性能问题还是内存问题。手动调用Collect 可能会损害性能,而不是帮助它。

【讨论】:

    【解决方案2】:

    在某些进程完成并杀死大量对象后,您应该可以随意调用 GC.Collect。处理 XML 文档是正确做法的典型示例。 任何告诉你永远不要调用 GC.Collect 的人只是在坚持他们所学到的通常正确但并非总是的内容。

    【讨论】:

    • 好吧,OP 说“内存永远不会被释放”,这表明对象甚至没有资格被收集,而不是内存释放得不够快。
    • 是的,我收到 OOM 错误(最终,即在处理 x # 个大型文档之后)。这是一个“愚蠢”的问题——这个函数(使用 mutex.WaitOne)在主线程上被调用。鉴于此,GC 会有机会做它的事吗?
    猜你喜欢
    • 2011-01-21
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 2012-05-04
    • 1970-01-01
    相关资源
    最近更新 更多