【发布时间】: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