.net - .NET CLR 上长时间运行的模拟应用程序

标签 .net memory clr

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

4 小时后,我们收到系统内存不足异常。

内存分析器向我们展示,如果我们权衡一些实时图形和其他一些未处理的对象,我们可以节省“一些”(35%-40%)内存。

我担心它仍然无法 24 小时不间断运行。我们的 HP 8440p Elitebook Intel i5 上已安装了 4GB RAM(安装了 32 位 Win7)。

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

非常感谢。

最佳答案

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

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

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

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

如果您怀疑内存泄漏:

这个article可能会有所帮助,它向您展示了如何使用 Windgb(高级调试器)来跟踪可能使不需要的陈旧引用保持事件状态的对象。

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

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

关于.net - .NET CLR 上长时间运行的模拟应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12780199/

相关文章:

c# - 为什么 MapInheritedProperties() 将我的实体映射到两个表中?

c# - 为什么 List IndexOf 允许超出范围的起始索引?

c# - .NET Core 中 AppDomain.GetLoadedAssemblies() 的替代品?

C: 使用带++/-- 的指针更新内存地址内容

c# - 使用 ClrMD 加载转储文件时为 "Failure loading DAC: CreateDacInstance failed"

c# - .NET如何定位命名空间的dll I'm `using` ?

memory - 拟合微分方程组参数时 Mathematica 内存不足

c - C 中的内存管理问题

c# - 语句 block 中的变量范围

clr - JVM/CLR 执行 native 代码