4

I have a method that needs to process a user-supplied file and if the file is complex enough I may encounter an OutOfMemoryException. In these cases I'm fine with the method failing however I would like the application to remain usable, the problem is that after getting an OutOfMemoryException I can't do anything since every course of action consumes memory.

I thought of putting aside some memory which I can free once the exception is throw so the rest of the application can carry on but it seems that the optimizer gets rid of this allocation.

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
    }
}

Long story short my questions are:

  1. Is there a better way to do what I'm attempting?
  2. If not, is there a good reason why this is a bad idea?
  3. Assuming this idea is the way to go, how do I force the JIT to not optimize away my wasted memory?
4

2 回答 2

2

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

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

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

于 2013-06-09T11:26:19.987 回答
1

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

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

此 SO 线程解释了 32 位 .NET 应用程序的内存限制。 在 32 位 .NET 进程中分配超过 1,000 MB 的内存

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

于 2015-03-15T15:24:56.037 回答