.NET CLR上运行时间长的仿真应用程序

时间:2012-10-08 10:49:43

标签: .net memory clr

我们编写了一个应用程序,它是一个需要24小时不间断运行的数字运算模拟。 它使用窗体形式的绘画事件来呈现连续的主题的可视化表示,此外我们使用几个实时图形和网格来显示项目对象的进度。它是一个.NET窗体应用程序。

4小时后,我们得到System outOfMemory Exception。

Memory Profiler告诉我们,如果我们权衡一些实时图形和其他一些未处理的对象,我们可以节省“一些”(35%-40%)内存。

我担心的是它仍然不会连续24小时不停。我们已经安装了32位Win7的HP 8440p Elitebook Intel i5上有4GB内存。

我们的目标是为我们的模拟应用程序和运行它的.NET CLR提供最大可能的内存供应。 是否会投入更多内存(可能是8GB)和64位操作系统?除了添加更多硬件外,还需要考虑哪些其他可能的CLR选项?

非常感谢。

2 个答案:

答案 0 :(得分:1)

应用是64位,在64位操作系统上运行吗? 32位CLR应用程序的上限非常低(低于2GB逻辑限制) - 但64位CLR应用程序应该能够使用非常大量的内存而不会出现问题。当物理内存用完时,64位应用程序也会翻页到磁盘 - 因此整个机器将耗尽物理内存并在从CLR收到OutOfMemory错误之前很久就开始分页到磁盘。

答案 1 :(得分:1)

@Adam Houldsworth的建议非常好。您可能面临内存泄漏(仍然保留对陈旧对象的引用,通常由Adam建议的实时事件订阅,这可以防止它们被垃圾收集)。

@mkimes的答案也很有价值。实际上,作为64位进程运行将允许您的应用程序管理更多内存,但仍有一些警告(例如单个对象大小的2GB限制)。

如果你直觉地认为应用程序不应该耗尽内存,因为在你的推理中,大多数创建的对象都是短暂的并且应该被处理掉,那么你可能正面临内存泄漏。但是,如果进程正在构建大量的对象,这些对象应该在进程完成后或在漫长的计算阶段期间保持活动状态,那么您可能会遇到32位内存限制障碍,特别是考虑到在完整期间垃圾收集周期,应用程序的内存将倾向于临时增长接近当前分配大小的两倍,保持实际的32位内存大小限制在1GB左右。

有一个Windows configuration switch允许增加32位应用程序可以处理到3GB的内存大小,但是根据我的经验,这使操作系统不稳定(非常频繁的蓝屏),因此请小心探索此选项。

如果您怀疑内存泄漏:

这个article可能有所帮助,它向您展示了如何使用Windgb(一种高级调试器)来跟踪可能使不需要的陈旧引用存活的对象。

另外(希望不是),你可能会成为一个非常讨厌的问题的受害者,这个问题是内存碎片,可以通过重复,频繁地分配CLR认为“大对象”的内容来引起,即大于85,000字节的对象尺寸。这是一个详细说明问题的article。基本上,这些对象是在不同的堆下分配的,但不幸的是,从未压缩过。这意味着释放的内存块将散布在已分配的块中,并且运行时可能在某些时候找不到单个连续的内存块来满足内存请求,从而触发内存不足异常。如果是这种情况,将大型整体对象分解为较小的对象将有所帮助。

最后,没有任何对象的大小可以大于2GB 即使在64位之下,所以你必须知道你的集合和/或数组没有达到这个限制。