从OutOfMemoryException恢复

时间:2013-06-09 11:11:55

标签: c# .net out-of-memory

我有一个方法需要处理用户提供的文件,如果文件足够复杂,我可能会遇到OutOfMemoryException。在这些情况下,我很好,方法失败但是我希望应用程序保持可用,问题是在获得OutOfMemoryException后我无法做任何事情,因为每个行动都消耗内存。

我想把一些内存放在一边,一旦异常被抛出我可以释放,所以应用程序的其余部分可以继续,但似乎优化器摆脱了这种分配。

public void DoStuff(string param)
{
    try
    {
#pragma warning disable 219
        var waste = new byte[1024 * 1024 * 100]; // set aside 100 MB
#pragma warning restore 219

        DoStuffImpl(param);
    }
    catch (OutOfMemoryException)
    {
        GC.Collect(); // Now `waste` is collectable, prompt the GC to collect it
        throw; // re-throw OOM for treatment further up
    }
}

长话短说我的问题是:

  1. 有没有更好的方法来做我正在尝试的事情?
  2. 如果没有,是否有充分理由说这是个坏主意?
  3. 假设这个想法是要走的路,我如何强迫JIT不优化我的waste内存?

2 个答案:

答案 0 :(得分:2)

如果已经清理了内存,我不会重新抛出OOM异常。

否则外部代码将不会知道,并且会认为它需要释放更多内存,而实际上并不需要。

所以我选择抛出自定义异常。

答案 1 :(得分:1)

如果是用户提供的文件,您可以在处理之前检查文件的大小:

FileInfo f = new FileInfo(fileName);
long s1 = f.Length;

此SO线程解释了32位.NET应用程序的内存限制。 Allocating more than 1,000 MB of memory in 32-bit .NET process

了解文件的大小和应用程序已经消耗的内存量可以检查您是否需要在尝试处理之前清理任何资源,或者您是否能够完成处理。