2

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

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

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

我担心的是它仍然不会 24 小时不间断运行。我们已经在安装了 32 位 Win7 的 HP 8440p Elitebook Intel i5 上配备了 4GB RAM。

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

非常感谢。

4

2 回答 2

1

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

于 2012-10-08T22:39:46.687 回答
1

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

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

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

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

如果您怀疑内存泄漏:

本文可能会有所帮助,它向您展示了如何使用Windgb(一种高级调试器)来跟踪可能使不需要的、过时的引用保持活动状态的对象。

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

最后,即使在 64-bits 下,任何对象的大小都不能大于 2GB ,因此您必须注意您的集合和/或数组未达到此限制。

于 2012-10-09T16:58:32.460 回答