Click here to Skip to main content
15,878,959 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello everyone!
I'm writing program to test memory leak. This is my code:
C#
public partial class Form1 : Form
   {
       Pen p = new Pen(Color.Red, 1.0f);
       Random d = new Random();

       public Form1()
       {
           DoubleBuffered = true;
           InitializeComponent();
           timer1.Start();
       }

       private void OnTimerTick(object sender, EventArgs e)
       {
           Invalidate();
       }

       private void OnForm1Paint(object sender, PaintEventArgs e)
       {
           Graphics g = e.Graphics;
           g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
           for (int i = 0; i < 100; i++)
           {
                g.DrawLine(
                    p,
                    d.Next(Width),
                    d.Next(Height),
                    d.Next(Width),
                    d.Next(Height));
           }
       }
   }

When i run this program and look at memory in "Windows task manager", I see memory of my program is increased .I do not understand why this is so? Can someone help me?
Sorry for my English!
Posted
Updated 9-Dec-14 1:37am
v2

OK, everyone is focused on the Pen. That's not the problem in the code you posted.

Well, there is one small problem where you're not disposing the Pen before your app terminates. This will lead to a handle leak and eventually break Window but you have to run this app over and over again, thousands of times, before that happens.

The problem is that you're looking at Task Manager to see how much memory your app is using. That's the WRONG place to look. It's showing you how much memory the .NET CLR has RESERVED for your application, not how much it's using.

If you want to see how much is actually is use, use PerfMon and the .NET memory counters or a CLR memory profiler to see what's actually being used.
 
Share this answer
 
GDI has great examples of unmanaged resources which developers are responsible for disposing after using.
In your example I see Pen and Graphic.
The graphic you are not creating so you dont have to release it.
The pen however, needs to be freed or released.

Try to put it in the eventhandler and dispose it after you draw.
Make the test and let me know if you have some improvement.'
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 9-Dec-14 11:24am    
Agree, but OP might need a bit more explanation on that. (I up-voted the answer with my 4.)
Please see my answer, more detailed one, in addition to yours.
—SA
In addition to Solution 1:

You have two options:


  1. You can create your instance of Pen the way you do and dispose it in this Form.Dispose method: http://msdn.microsoft.com/en-us/library/aw58wzka%28v=vs.110%29.aspx[^].

    This is the approach designed to chain disposal in a set of UI elements (or some other objects you would want to design yourself) according to their parent-child relationships.
  2. Also, you can create an instance of your pen where you use it (in your overridden OnPaint method or your handler of the event Paint and dispose immediately after use. The best way to do it is using the using statement:
    C#
    using (Pen pen = new Pen(Color.Red, 1.0f))
    {
        for (int i = 0; i < 100; i++)
                {
                     g.DrawLine(
                         p, 
                         d.Next(Width), 
                         d.Next(Height), 
                         d.Next(Width), 
                         d.Next(Height));
                }
    } // pen.Dispose is automatically called here

    Not that pen.Dispose will be called even of an exception is thrown. Please see: http://msdn.microsoft.com/en-us/library/yh598w02.aspx[^].


Unmanaged memory leaks are usual when you use GDI. The simple rule is: watch out for all objects; check up if they implement System.IDisposable. If they do, make sure you dispose them. See also: http://msdn.microsoft.com/en-us/library/system.idisposable%28v=vs.110%29.aspx[^].

Also, managed memory leak is possible, but that could be a result of wrong design. This is a different story…

—SA
 
Share this answer
 
Comments
[no name] 9-Dec-14 14:15pm    
I created the Project with OP code and tested it.
a.) Memory usage does increase continuously...but with time in a slower rate.
b.) I checked also your Suggestion using(...). creating/disposing the Pen each OnPaint makes the whole Thing more worse.

I think it is not a Memory leak, it is more the behaviour of GC.
Sergey Alexandrovich Kryukov 9-Dec-14 14:53pm    
Well, it's not all as simple as that.

Your first observation is correct. But it also depends on how you observe the memory consumption. For example, TaskManager cannot be considered as a reliable or accurate source of information; some memory debugger could be used.
No, I cannot believe that using "using" can make thing works. It could be so only in combination with some other factors. I cannot also believe that GC can be blamed. Anyway, GC is unrelated to the unmanaged memory. It disposes the instance of the object (like Pen), when one becomes unreachable, but not immediately, but unmanaged memory is reclaimed only by Dispose. Anyway, not calling Dispose is not an option at all. It should be called on each object which type implements System.IDisposed, period.

If one has too many objects to create and dispose, first approach could be better. For just one pen, I would go with "using"...

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900