System.Drawing Out of Memory Exception
My application graphics engine throws these exceptions. They are all consumed by an empty catch block. In the early days I found one that was not trapped (associated with pen widening as I recall). I surrounded it with try and an empty catch block. It seems that these exceptions have no effect on the drawing produced. I have done some reading on this without really understanding or getting to the bottom of it.
So to my questions:
- Why would these be thrown if they can be consumed safely? and
- Is it safe to ignore them? I worry that each one is having some hidden effect. I have memory leaks which I have never found for example.
I've seen System.Drawing throw OutOfMemoryExceptions even when it's not out of memory. Some GDI+ function is apparently just returning a stupid error code.
IIRC, you will get an OutOfMemoryException if you try to use a LinearGradientBrush to fill a rectangle whose width or height is zero. There may be other conditions too, but this is the main one we ran into.
In that case, there's no need for a try/catch. Just add an if
statement to your drawing code, and don't fill the rectangle if the width or height is zero.
Update: According to the comments on this answer, it can also occur if you try to load a corrupted image file. For that, you would have no choice but to do try/catch.
You're probably safe catching OutOfMemoryExceptions from GDI+, but keep the try blocks as small as possible. Consider logging the exceptions, so you can analyze the logs and add defensive code where possible. You don't want to mask a real OutOfMemoryException, but you don't want a stupid GDI+ error code to crash your app either.
It's a pretty bad exception: http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx .. not enough memory to continue execution of the program.
You'll often find if you have so much allocated that 'simple' operations/allocations throw this message, the app will crash soon after. If it's one massive allocation that's failing, you may be able to continue.
If the app does anything important, you should try to close things down gracefully.
To explicitly answer your questions:
They're thrown so the app has a chance to react/recover: some memory allocations (10GB worth of objects) might be expected to fail in many situations, perhaps a one-line app crash (
int[] x = new int[5368709120];
equivalent) should really throw an exception rather than crash everythingThere should be no hidden effect, but if one allocation fails, then perhaps the next time you want a
string
or other useful object in some small way allocated for general operation of the app: things might become unstable. That said depending on the environment, you might get this exception at any time..
Edit: Anyone reading this should also consider that apparently GDI+ throws this exception for other reasons too.