Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  1. Why would these be thrown if they can be consumed safely? and
  2. 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.
like image 877
ScruffyDuck Avatar asked Jun 28 '11 12:06

ScruffyDuck


People also ask

What causes system out of memory exception?

An OutOfMemoryException exception has two major causes: You are attempting to expand a StringBuilder object beyond the length defined by its StringBuilder. MaxCapacity property. The common language runtime cannot allocate enough contiguous memory to successfully perform an operation.

How do I stop out of memory exception?

Well, according to the topic of the question, best way to avoid out of memory exception would be not to create objects that fill in that memory. Then you can calculate the length of your queue based on estimate of one object memory capacity. Another way would be to check for memory size in each worker thread.


2 Answers

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.

like image 65
Joe White Avatar answered Oct 04 '22 02:10

Joe White


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:

  1. 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 everything

  2. There 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.

like image 20
Kieren Johnstone Avatar answered Oct 04 '22 03:10

Kieren Johnstone