.NET中OutOfMemoryException的try / catch块的设计模式

时间:2011-07-09 14:27:26

标签: .net try-catch idisposable out-of-memory

我有一个可以处理大量数据的应用程序,我想,有时可能会抛出OutOfMemoryException(半年来,我没有一个例外,但是我'我只想知道一切。)正如我所调查的那样,在此异常之后,我无法继续执行我的程序。

是否有任何良好的模式来处理此类异常,尤其是使用IDisposable类?

3 个答案:

答案 0 :(得分:4)

没有好的模式,OOM是一个令人讨厌的例外,随时都可能发生。这使得几乎异步异常。处理它的唯一几率是你的代码构造成同时分配大量内存。因此,你可能会有一些机会退出并解除程序状态,好像什么都没发生一样。

您需要设计您的程序,因此它永远不需要分配超过所有可用虚拟内存的一半,在32位计算机上分配一千兆字节。龙超过这个数量,你的程序将在90 MB或更少的分配上失败,即使还有另外500 MB的虚拟内存未使用。地址空间碎片引发的问题。如果您经常跨越此阈值,则需要切换到64位操作系统。

答案 1 :(得分:4)

在真正的OOM场景中(更有可能在x86而不是x64上),你在那里注定要失败。几乎任何东西都会导致分配,所以你最好的选择是尽可能快速和优雅地死去,尽量减少伤害。

由于没有发生,不要过分强调,但避免比在此处理更好:

  • 使用流式数据API而不是缓冲内存中的所有内容
  • 重复使用缓冲区等
  • 避免巨大的数组/列表/等(实际上,导致OOM的最可能方式是请求一个巨大的(但是单个的)数组) - 例如,锯齿状数组比2D数组更好(甚至在x64上)对单个阵列的最大大小有一个硬性限制)
  • 考虑如何处理稀疏数据
  • 你从外部来源读了很多字符串吗?如果是这样,请考虑使用自定义内部工具,这样就不会有20,000个不同的常用字符串副本(例如,国家/地区名称)
  • 留意
  • 时释放的内容
  • 避免意外延长对象的生命,特别是通过事件订阅(因意外延长生命周期而臭名昭着)

答案 2 :(得分:2)

我之前的两个答案是正确而合理的建议,
但他们没有提到过一件事 - 负载测试 如果您担心在某些负载下,您的应用程序可能会耗尽内存 - 请针对该负载进行测试(最好是更大的负载)。

在我以前的工作中,我使用了这样一个工具(HP's Performance Center),它不仅可以检查我们系统的错误和限制,还可以识别瓶颈和昂贵的操作。