Jari Nevala

Jari Nevala

  • NA
  • 35
  • 34k

Why does this simple application run out of memory after a few minutes?

Jul 13 2010 8:59 AM
Hi all,

I have this really simple application that has a timer. Every time the timer "ticks" (the interval is set to 1 ms) a screenshot is taken (a new Bitmap object is created and a 100x100 pixel portion of the screen is copied into the Bitmap object).  Also a labelĀ“s text is updated to display time since starting the timer.

The weird thing is that I get a "Out of memory" exception after the timer has been running a couple of minutes. I tried changing the interval, but I get the same error whether the timer is 1, 10 or 100 ms.

Can someone please explain why this happens? Clearly I have some kind of memory leak in my app, but the only disposable resource I have is the Graphics object, and I think I do dispose it properly. I would like to understand the reason behind this behavior.

Here is (most interesting parts of) the code. The whole solution is attached as .zip.

---Code snippet start---
 public partial class Form1 : Form
    {
        DateTime startTime;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            startTime = DateTime.Now;
            timer1.Start();                       
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Bitmap bitmap = GetScreenShot();
            TimeSpan duration = DateTime.Now - startTime ;
            label1.Text = duration.ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Stop(); 
        }

        public Bitmap GetScreenShot()
        {
            Bitmap screenShotBMP = new Bitmap(100, 100, PixelFormat.Format32bppArgb);
            Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);
            try
            {
                screenShotGraphics.CopyFromScreen(100, 100, 0, 0, new Size(100, 100), CopyPixelOperation.SourceCopy);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: "+ex.Message );
            }
            finally
            {
                screenShotGraphics.Dispose();
            }
            return screenShotBMP;
        }

    }

---Code snippet end---

Here is the error that I get:

----Error start----
Error: Out of memory.    at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)    at System.Drawing.BufferedGraphicsContext.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)    at System.Drawing.BufferedGraphicsContext.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)    at System.Drawing.BufferedGraphicsContext.Allocate(IntPtr targetDC, Rectangle targetRectangle)    at System.Windows.Forms.Control.WmPaint(Message& m)    at System.Windows.Forms.Control.WndProc(Message& m)    at System.Windows.Forms.Label.WndProc(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)    at System.Windows.Forms.Application.Run(Form mainForm)    at TestUIDeleteThis.Program.Main() in C:\Users\Visual Studio 2008\Projects\TestUIDeleteThis\TestUIDeleteThis\Program.cs:line 20
----Error end----

-Jari

Attachment: TestUIDeleteThis.zip

Answers (51)