none
Catching OutOfMemoryException RRS feed

  • Question

  • We're working on a server application, and sometimes under heavy stress OutOfMemoryExceptions show up, (Not allocating a lot of small objects, always when allocating large arrays so I'm able to catch them).

    I'm wondering what the potential consequenses of catching an OutOfMemoryException would be ? I Remember reading something about corrupted state? But is it the CLR / heap manager itself that might get corrupted or is it just the possibility that the applications are inconsistent if interrupted by OutofMemoryExceptions ?

    I tried using a MemoryFailPoint - but I still get OutOfMemoryExceptions even though MemoryFailPoint is succesful.

    Code:

     private static object staticLock = new object();

    public static int[] CreateInt32Array(int capacity)
    {
     lock (staticLock)
     {
      //12 bytes overhead + 4 bytes per Int32 element                   
      int expectedMemoryUsageInMegabytes = ((12 + 4 * capacity) + (1 << 20 ) - 1) >> 20;
      using (new MemoryFailPoint(expectedMemoryUsageInMegabytes))
      {
       return new int[capacity];
      }
     }
                  
    }

     

    Thursday, January 4, 2007 12:27 PM

Answers

  • Hi Jesper

    Catching OutOfMemoryExceptions is discouraged because of the possibility of inconsistent state in your application, not the runtime.  Since OOM is an asynchronous exception (can happen at any point, on any thread), you can't guarantee the state of your application if you catch it (especially a multi-threaded app).  Aside from that, in the general case there isn't a lot you can do once you catch an OOM, so it's best to let the application die.

    Maoni's blog post about debugging OOMs may be helpful to you:
    http://blogs.msdn.com/maoni/archive/2005/05/06/415296.aspx

    Hope that helps

    -Chris

    Thursday, January 4, 2007 6:54 PM

All replies

  • Hi Jesper

    Catching OutOfMemoryExceptions is discouraged because of the possibility of inconsistent state in your application, not the runtime.  Since OOM is an asynchronous exception (can happen at any point, on any thread), you can't guarantee the state of your application if you catch it (especially a multi-threaded app).  Aside from that, in the general case there isn't a lot you can do once you catch an OOM, so it's best to let the application die.

    Maoni's blog post about debugging OOMs may be helpful to you:
    http://blogs.msdn.com/maoni/archive/2005/05/06/415296.aspx

    Hope that helps

    -Chris

    Thursday, January 4, 2007 6:54 PM
  • Thanks, this helps a lot.

    The function calls where I want to catch the OOM exceptions don't change any state in the applications, as they are pure readers. Some queries might need a lot of temporary data in some fairly large arrays (up to a couple of MB), and since the application is already running with a virtual machine size of 1 - 1.2 GB there is a fragmentation issue, especially with concurrent queries. This is in some ways good news because it means that the typical situation is that there's plenty of space left for smaller objects, making it possible to just cancel the query thereby releasing its ressources (which means plenty of space to execute any disposers / lock releases placed in finally() blocks) .

    As long as I can be assured that an OutOfMemoryException thrown in a given thread never changes any state that isn't changed by code in that thread all is well. (If the OOM condition that caused the exception creates problems for other threads then it would be in the form of an exception in these threads also?).

    We have discussed using the 3GB switch, but the last time we tried we couldn't even boot into Windows. It was suggested that assumptions in driver software might be the problem. Because of this, and also because we're unsure of how our 3rd party unmanaged dlls would handle addresses > 2GB we're a little cautious here.

    On the subject of OutOfMemoryExceptions occuring inside memory gates I think it is caused by concurrent allocation of memory outside gates causing fragmentation of the heap - at least I can create minimum cases demonstrating this. This is of course also to be expected as MemoryFailPoint doesn't reserve memory.

     

    Friday, January 5, 2007 8:57 AM