Motti
Motti

Reputation: 114825

Recovering from OutOfMemoryException

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?

Upvotes: 4

Views: 1636

Answers (2)

Shar1er80
Shar1er80

Reputation: 9041

If it's a user supplied file, you could check the size of the file before processing it:

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

This SO thread explains the memory limits of a 32-Bit .NET application. Allocating more than 1,000 MB of memory in 32-bit .NET process

Knowing the size of the file and the amount of memory the application is already consuming can be your check if you need to clean up any resources before attempting to process, or if you'll be able to process at all.

Upvotes: 1

Vlad
Vlad

Reputation: 35594

I wouldn't rethrow an OOM exception, if the memory is already cleaned up.

Otherwise the outer code won't know that, and will think that it needs to free some more memory, whereas it actually doesn't need to.

So I'd opt for throwing a custom exception.

Upvotes: 2

Related Questions