title: Why is my c# paint method running out of memory?
body: <p>I'm new to c#, and trying to learn by writing some simple apps to get familiar with the syntax and .NET library.  The most recent miniproject I took on is a polar clock <a href="https://mbostock.github.io/protovis/ex/clock.html" rel="nofollow noreferrer">like the one found here</a>.</p>
  
  <p>One of the problems I noticed early on was that the app would constantly "flicker", which really took away from the presentation, so I read online about how to implement a double buffer, which eliminated this problem, but may or may not have something to do with the problem.  Here is my <code>onPaint</code> method; it is called every 33ms (~30 FPS) by a timer control.  Most of the rest of the app is simply handlers for dragging the app (since it is frameless and has a transparent background), exiting on double-click, etc.</p>
  
  <pre><code>    protected override void OnPaint(PaintEventArgs e) {
          DateTime now = DateTime.Now;
  
          float secondAngle = now.Second / 60F;
          secondAngle += (now.Millisecond / 1000F) * (1F / 60F);
  
          float minuteAngle = now.Minute / 60F;
          minuteAngle += secondAngle / 60F;
  
          float hourAngle = now.Hour / 24F;
          hourAngle += minuteAngle / 60F;
  
          float dayOfYearAngle = now.DayOfYear / (365F + (now.Year % 4 == 0 ? 1F : 0F));
          dayOfYearAngle += hourAngle / 24F;
  
          float dayOfWeekAngle = (float)(now.DayOfWeek + 1) / 7F;
          dayOfWeekAngle += hourAngle / 24F;
  
          float dayOfMonthAngle = (float)now.Day / (float)DateTime.DaysInMonth(now.Year, now.Month);
          dayOfMonthAngle += hourAngle / 24F;
  
          float monthAngle = now.Month / 12F;
          monthAngle += dayOfMonthAngle / (float)DateTime.DaysInMonth(now.Year, now.Month);
  
          float currentPos = brushWidth / 2F;
  
          float[] angles = {
              secondAngle, minuteAngle,
              hourAngle, dayOfYearAngle,
              dayOfWeekAngle, dayOfMonthAngle,
              monthAngle
          };
  
          SolidBrush DateInfo = new SolidBrush(Color.Black);
          SolidBrush background = new SolidBrush(Color.Gray);
          Pen lineColor = new Pen(Color.Blue, brushWidth);
          Font DateFont = new Font("Arial", 12);
  
          if (_backBuffer == null) {
              _backBuffer = new Bitmap(this.Width, this.Height);
          }
  
          Graphics g = Graphics.FromImage(_backBuffer);
          g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
  
          try {                
              g.Clear(Color.White);
              if (_mouseIsOver) {
                  g.FillEllipse(background, new Rectangle(0, 0, this.Width, this.Height));
              }
              foreach (float angle in angles) {
                  g.DrawArc(
                      lineColor,
                      currentPos, currentPos,
                      this.Height - currentPos * 2, this.Width - currentPos * 2,
                      startAngle, angle * 360F
                  );
  
                  currentPos += brushWidth + spaceStep;
              }
  
              // Text - Seconds
  
              g.DrawString(String.Format("{0:D2} s", now.Second), DateFont, DateInfo, new PointF(115F, 0F));
              g.DrawString(String.Format("{0:D2} m", now.Minute), DateFont, DateInfo, new PointF(115F, 20F));
              g.DrawString(String.Format("{0:D2} h", now.Hour), DateFont, DateInfo, new PointF(115F, 40F));
              g.DrawString(String.Format("{0:D3}", now.DayOfYear), DateFont, DateInfo, new PointF(115F, 60F));
              g.DrawString(now.ToString("ddd"), DateFont, DateInfo, new PointF(115F, 80F));
              g.DrawString(String.Format("{0:D2} d", now.Day), DateFont, DateInfo, new PointF(115F, 100F));
              g.DrawString(now.ToString("MMM"), DateFont, DateInfo, new PointF(115F, 120F));
              g.DrawString(now.ToString("yyyy"), DateFont, DateInfo, new PointF(115F, 140F));
  
              e.Graphics.DrawImageUnscaled(_backBuffer, 0, 0);
          }
          finally {
              g.Dispose();
              DateInfo.Dispose();
              background.Dispose();
              DateFont.Dispose();
              lineColor.Dispose();
          }
          //base.OnPaint(e);
      }
  
      protected override void OnPaintBackground(PaintEventArgs e) {
          //base.OnPaintBackground(e);
      }
  
      protected override void OnResize(EventArgs e) {
          if (_backBuffer != null) {
              _backBuffer.Dispose();
              _backBuffer = null;
          }
          base.OnResize(e);
      }
  </code></pre>
  
  <p>I thought by disposing of everything at the end of the method I'd be safe, but it doesn't seem to help.  Furthermore, the interval between run-time and the OutOfMemoryException isn't constant; once it happened only a few seconds in, but usually it takes a minute or two.  Here are some class-wide variable declarations.</p>
  
  <pre><code>    private Bitmap _backBuffer;
  
      private float startAngle = -91F;
      private float brushWidth = 14;
      private float spaceStep = 6;
  </code></pre>
  
  <p>And a screenshot (edit: screenshot links to a view with some code present):</p>
  
  <p><a href="https://www.ggot.org/inexplicable/pc.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1eWrR.jpg" alt="Screenshot"></a><br>
  <sub>(source: <a href="http://www.ggot.org/inexplicable/pc2.jpg" rel="nofollow noreferrer">ggot.org</a>)</sub>  </p>
  
  <p>EDIT: Stacktrace!</p>
  
  <pre><code>System.OutOfMemoryException: Out of memory.
     at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
     at System.Drawing.Graphics.DrawArc(Pen pen, Single x, Single y, Single width, Single height, Single startAngle, Single sweepAngle)
     at PolarClock.clockActual.OnPaint(PaintEventArgs e) in C:\Redacted\PolarClock\clockActual.cs:line 111
     at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
     at System.Windows.Forms.Control.WmPaint(Message&amp; m)
     at System.Windows.Forms.Control.WndProc(Message&amp; m)
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
     at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  </code></pre>
  
  <p>Seems to be the same line it crashed on last time, the main <code>drawArc</code> inside the loop.</p>