我有一个应用程序:
- 针对 C# 6
- 目标.net 4.5.2
- 是 Windows 窗体应用程序
- 在 AnyCPU 模式下构建,因为它...
- 利用无法升级到 64 位、非托管内存的旧 32 位库
- 使用第三方控件供应商 DevExpress
- 每天处理数 GB 的数据以生成报告
在具有许多绘图的作业中使用几个小时后,应用程序最终会耗尽内存。根据性能计数器,我花了很长时间清理代码中发现的许多泄漏,并且已经使项目处于最坏的情况下,它可能在任何给定时间使用超过 400,000K 的内存。由于数据是在锯齿状数组中处理的,因此处理此数据目前没有产生任何问题,从而防止了大对象堆的任何问题。
上次发生这种情况时,用户使用了大约 305,000K 的内存。该应用程序是如此“内存不足”,以至于错误对话框甚至无法在出现的 MessageBox 中绘制错误图标,该图标通常所在的空间全是黑色的。
到目前为止,我已经完成了以下工作来清理它:
- Windows 窗体利用 Disposed 事件来确保清理资源,需要时手动调用 dispose
- 业务对象利用 IDisposable 删除引用
- 使用 ANTS 内存分析器和 SciTech 内存分析器验证清理。低内存使用表明情况并非如此,但我想看看我是否看到任何可能有帮助的东西,我不能
- 利用 GCSettings.LargeObjectHeapCompactionMode 属性从处理大对象堆 (LoH) 中可能碎片的数据中删除任何碎片
几乎每一篇我曾经到过这一点的文章都表明内存不足实际上意味着连续的地址空间不足,并且考虑到正在使用的数量,我同意这一点。我不确定此时该做什么,因为据我了解(并且可能非常错误)是垃圾收集器会在进程进行时清除它以腾出空间,除了 LoH,它是现在使用 .net 4.5.1 中引入的新 LargeObejctHeapCompactionMode 属性手动清理。
我在这里想念什么?我无法构建到 64 位,因为旧的 32 位库包含我们无法访问的专有算法,甚至梦想生产 64 位版本。我应该使用这些配置文件中的任何模式来准确识别这里失控的情况吗?
如果这个地址空间不能被清除,这是否意味着所有的 c# 应用程序最终都会因此而运行“内存不足”?