【问题标题】:OutOfMemoryException thrown only when compiling in release仅在发布时编译时抛出 OutOfMemoryException
【发布时间】:2014-05-28 20:14:30
【问题描述】:

我有一个分配大量小对象和数组的 C# 控制台应用程序。这些对象的生命周期很短,很快就会被垃圾收集器清理掉。对于“为什么需要分配这么多寿命短的对象,你应该避免这种情况”的问题:该程序用于繁重的 AI 任务,目前没有明显的方法来解决这个问题.

问题来了:

如果我在调试模式 x86 下运行程序,它运行良好并在几分钟后完成所有处理。平均而言,它使用 300-400 MB。

如果我采用完全相同的程序,但在发布 x86 模式下编译和运行它,程序使用的内存很快达到 2GB(在几秒钟内),因此它会抛出一个 OutOfMemoryException(这是预期的行为,因为它是32 位应用程序)。在release x64模式下编译根本解决不了问题,很快就用完了电脑的所有内存(8GB),然后内存分配失败就崩溃了。

我使用 SharpDevelop 4.3.3 来构建应用程序。调试模式和发布模式的唯一区别是:

  • 优化代码(仅限发行版)
  • 检查算术上溢/下溢(仅限调试)
  • 调试信息:完整的调试信息(调试)/无调试信息(发布)

在所有情况下都没有附加调试器。程序非常短,并且没有编译器指令可以使它在调试或发布时以不同的方式运行。 没有明显的理由来解释这种行为。在发布模式下编译时,看起来垃圾收集器从未被触发(或至少没有足够的时间)并且内存没有被释放。

似乎similar question 已被询问,但似乎与我的问题不同。

【问题讨论】:

  • 您能否打开和关闭这些功能以进行发布?如果你打开artithmetic overflow/underflow,它还会爆炸吗?好奇这是不是在做一些奇怪的事情,让程序在它可能不应该工作的时候工作。
  • 我尝试在发布中设置与调试中完全相同的设置(优化代码已关闭,检查算术,调试信息已满):它没有帮助。现在两种模式之间唯一剩下的区别在于conditional compilation symbols:调试使用DEBUG;TRACE,而发布使用TRACE
  • 那时我唯一能想到的就是抓一个像 dotPeek 这样的反汇编程序并检查两个应用程序之间的区别。
  • 发布复制代码。 sscce.org

标签: c# garbage-collection out-of-memory compile-mode


【解决方案1】:

如果终于找到原因了。我的错。

我有一个Debug.Assert() 方法调用,它不仅执行一些检查,还执行一些操作(例如:Debug.Assert(List.Remove()))。

我假设Debug.Assert() 在两种情况下(发布和调试)都会执行,并且结果值仅在调试模式下进行测试,但这是错误的。在发布模式下编译时,Debug.Assert() 调用完全从代码中删除。

我给出了答案,并没有结束问题,因为它可能对其他人有用。

【讨论】:

    【解决方案2】:

    您可以在代码中添加调用来强制垃圾收集器运行。例如:

        GC.Collect();
        GC.WaitForPendingFinalizers();
    

    但是,我怀疑垃圾收集器实际上正在运行,所以这不会产生显着影响。最佳实践建议是不要试图超越垃圾收集器。我建议这样做只是为了证明问题不存在。

    通常当程序消耗所有可用内存时,某些东西会保留对对象的引用,以致 GC 无法释放它们。

    面对这个问题,我会使用某种内存分析器来确定哪些内容没有被释放,哪些内容保留了它。您可以使用多种 .NET 内存分析工具。 (我不确定他们在发布代码方面有多好)。我可能会尝试使用 JetBrains dotMemory 的免费试用版。我没有亲自使用过它,但我发现他们提供的其他分析工具很有帮助。

    顺便说一句,不要为使用依赖于许多短期对象的设计模式而道歉。这是一种完全可以接受的设计模式。有一些编程语言是编写代码的唯一方法。

    【讨论】:

    • 如果垃圾回收没有运行是问题,他应该在调试版本中也看到这个问题。如果有的话,GC 在调试版本中较少积极。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多