-2

I have a draw function which draws lines that are gradient from one end to the other. I'm only drawing about forty or so lines each time. Each time, I generate a new set of Linear gradient brushes. The old set is a local variable with no ties to any object. My program only uses about 26 MB of memory. It'll work fine for several minutes before randomly throwing an out of memory exception when allocating a new linear gradient brush. As you can see, memory was at 25.7 MB when the exception occurred.

Minimal Example Code (will throw the memory exception):

Note: The following code only triggers the exception if it is used in a redraw for the graphics context, that context is resized, and even then, only after several minutes.

class DrawImpl
{
    private static Pen routePen = new Pen(Color.Black);
    public static void Draw(Graphics g, Point[] ps)
    {
        g.SmoothingMode = SmoothingMode.HighQuality;            
        if (ps != null && ps.Length > 0)
        {
            for (int i = 0; i < ps.Length; ++i)
            {
                int prevI = (((i - 1) % ps.Length) + ps.Length) % ps.Length;
                using (LinearGradientBrush routeBrush = new LinearGradientBrush(ps[prevI], ps[i], Color.Red, Color.Blue))
                {
                    routePen.Brush = routeBrush;
                    g.DrawLine(routePen, ps[prevI], ps[i]);
                }
            }
            GC.Collect();
        }
    }
}
AaronF
  • 2,841
  • 3
  • 22
  • 32
  • I have it in 64 bit. – AaronF Mar 31 '17 at 19:52
  • can you show the code for the draw function? – Ousmane D. Mar 31 '17 at 19:56
  • You should paste some code. Until then all I can do is agree with your debugger. – djv Mar 31 '17 at 19:56
  • 1
    Let me guess: you're not calling `Dispose()` on the brushes or using `using` blocks? – adv12 Mar 31 '17 at 20:02
  • That is correct. I wasn't aware that I needed to. Thanks. I'll try it. – AaronF Mar 31 '17 at 20:58
  • It didn't work. Running the example code each time a form is updated will eventually lead to the exception. – AaronF Mar 31 '17 at 21:48
  • See also [this](http://stackoverflow.com/questions/25723855/outofmemoryexception-out-of-memory-system-drawing-graphics-fromimage) – Massimiliano Kraus Apr 01 '17 at 21:08
  • How are you getting your `Graphics` objects? If you're using just the ones passed into `OnPaint`, your code looks fine; if you're creating them with `CreateGraphics` (which is usually a sign you're doing something wrong), you need to `Dispose()` those too. – adv12 Apr 03 '17 at 13:34
  • I'll have to look into that when I return to this probject. I'm not the one who wrote the code that gets the Graphics object. Massimiliano Kraus: I noticed in the question you found that it says an out of memory exception can occur if the rectangle has zero width or height. That may well be the issue, though it doesn't make sense since I'm shading a line that might need to be horizontal or vertical. I'll check it out. Thanks for finding that. If that post turns out to answer the question, I'll confirm this as a duplicate. – AaronF Apr 03 '17 at 23:21
  • I was able to draw a vertical gradient defined by the same two points used to draw the line, without an exception. – AaronF Apr 04 '17 at 02:46
  • However, I was able to consume the exceptions without consequence. – AaronF Apr 04 '17 at 02:48

1 Answers1

0

Unfortunately, System.Drawing can throw OutOfMemory exception even when the error has nothing to do with memory.

I have seen people encounter that exception in the following scenarios: * Using a LinearGradientBrush to fill a rectangle with dimension(s) of 0 * Trying to load a corrupted image file

These exceptions come from GDI+ so I would suggest to look for inner exceptions and logs.

Dmytro Bogatov
  • 776
  • 1
  • 10
  • 23