Memory leak in C#?????

  • Thread starter Thread starter john
  • Start date Start date
J

john

I have a button on a form, and when you click the button, it performs
the following:

using (FormMS f = new FormMS())
{
f.ShowDialog();
}

The new form that is shown (FormMS) has a DataGrid that gets bound to
a large DataTable. The DataTable is static so it only gets created
once. So I open FormMS as a dialog and then close it. I continue to
open and close it several times and each time, the memory used by my
application goes up a lot. It doesn't seem to deallocate the memory
needed by the DataGrid. I try calling GC.Collect() after the FormMS
closes and it doesn't do the trick. I tried letting the application
sit overnight to see if it would deallocate the memory and that
doesn't work. I try calling the DataGrid.Dispose method inside my
FormMS.Dispose method and that doesn't work. I have to restart the
application to get it to deallocate the memory. I keep opening it
again and again to see if I must use up all my physical memory before
it deallocates, and that doesn't work either.

Any ideas?
Thanks in advance.
 
What version of the framework are you using?

Check to ensure that you are calling Dispose(). Calling Close() should in
turn call Dispose(), but setting a DialogResult will simply Hide() the form.
Check the docs on that one! It was a shock to me. Try putting a break point
inside the Dispose() method and see if you hit it.

If that doesn't work...
Manually unregister ALL events between the form (and it's controls) and the
DataTable. You may have to peak into the InitializeComponent block to see
them (or do a ctrl+shift+f for += to list them out) Surprisingly, you can
use -= new EventHandler to remove an event so you don't have to keep class
level variables of the delegates.

For example:
cmdClose.Click -= new EventHandler(this.cmdClose_Click))

I had a similar leak with a static object. It was holding a reference back
to other classes via the events. Since a static object has a lifetime
equivalent to that of the process, any hung references are never collected.
Also call Dispose on EVERYTHING that exposes it, and set all references to
null. Do all of this in the Dispose method of the form and again be sure
that it's being called.

Changing a static object variable to an instance variable corrected the
issue for me, but in my case making it static in the first place was
mistake.

There are also documented leaks with DateTimePicker and NumericUpDown. A
detail of that issue, and a memory profiler can be found here:

http://www.automatedqa.com/techpapers/net_allocation_profiler.asp
or
http://www.scitech.se/memprofiler/


HTH,
Eric Cadwell
http://www.origincontrols.com
 
Memory usage growth is normal, as the GC is triggered by memory, not by
Dispose(). If you can continue opening and end up with a crash, you have a
problem. If it ultimately GCs, you are fine.

You can manually trigger the GC, if you are really concerned, but it is not
advised.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

**********************************************************************
Think Outside the Box!
**********************************************************************
 
What version of the framework are you using?

I am using the most recent (1.1 I think).
Check to ensure that you are calling Dispose(). Calling Close() should in
turn call Dispose(), but setting a DialogResult will simply Hide() the form.
Check the docs on that one! It was a shock to me. Try putting a break point
inside the Dispose() method and see if you hit it.

The Dispose() method of the FormMS is being called because I
instantiate it using the keyword "using". I have put a breakpoint in
Dispose() to confirm this.
I had a similar leak with a static object. It was holding a reference back
to other classes via the events. Since a static object has a lifetime
equivalent to that of the process, any hung references are never collected.
Also call Dispose on EVERYTHING that exposes it, and set all references to
null. Do all of this in the Dispose method of the form and again be sure
that it's being called.

There are no references between the DataTable and the form through
events. In the method FormMS.Dispose() I tried setting the DataGrid's
DataSource property to null so it would no longer have a reference to
the DataTable. That didn't work either.

This is really weird. Any other ideas?
 
Back
Top