I am trying to reduce memory usage of a winForm application.
There is a main form and a setting form in the application. When "Setting" button been pressed, the setting form will popup as a modal form, the Setting form will load app.config data from config file and read them to memory as Hashtab开发者_Go百科le. After the setting form closed, it will call Dispose method inherented from Windows.Forms.Form. The Dispose method is as simple as set the Hashtables and app.config object to null.
Show SettingForm as modalform:
private void btnSettings_Click(object sender, EventArgs e)
{
frmConfig form = new frmConfig();
form.StartPosition = FormStartPosition.CenterScreen;
//MessageBox.Show(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase));
form.ShowDialog(this);
form.Dispose();
}
Dispose method:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
// Release managed resources
Logger.Verbose("Disposing SettingForm");
mySetting = null;
testFtp = null;
}
base.Dispose(disposing);
}
Note: mySetting is a instance of Class with all the app.config data been load into Hashtable, and testFtp is a custom object for ftp function. Should I implement Dispose method for this two class and using
mySetting.Dispose();
testFtp.Dispose();
instead of set them to null, as they are themself/deal with unmanaged resources?
But each time push the "Setting" button and close the setting form will increase private Byte for a few hundreds K. Memory leak? How could I get rid of it?
As you suggested near the end of your question, I would recommend implementing IDisposable on mySetting
and testFtp
. You should see better cleanup of resources once you have implemented the following:
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
// Release managed resources
Logger.Verbose("Disposing SettingForm");
mySetting.Dispose();
testFtp.Dispose();
}
base.Dispose(disposing);
}
Small edit:
Based on Nayan's answer and the answer he links to: I'd highly recommend the implementation of IDisposable
. Using Forms
and deriving from the Forms
class screams, "Check for the need to implement IDisposable
." This does not mean that your code should be implementing it, just that you should really check to make sure you don't need it. Forms typically have a lot of events published and subscribed to. Forms are also notorious for becoming a catch-all resource bucket, IMO.
The memory may not be getting released because of some other piece of code too. Since you have not provided much details, I'll assume right now that everything else is optimal.
The objects that you are working with are collected by garbage collector (as you know it). But they may not be released from memory when you want it. .NET objects are better left to garbage collector.
As per why the memory may not be getting released, you have the answers here.
Setting object reference to null doesn't make much difference. On the other hand, I've personally recorded some times, objects coming back alive (and pushed to old generations) because you're using them while setting null to same. It's another form of interference with GC, but your choice.
You may not need to implement IDisposable
, but if you are working with streams, OS handles, unmanaged resources, you should then.
Edit:
The memory usage may be high, but it's GC's responsibility to free it as long as you do not keep references alive. So, if you have taken every precaution, it still may seem that your application is consuming lot of memory. That is acceptable as freeing the unreferenced objects is garbage collector's responsibility.
Why do you think it's a leak? GC is not obliged to free memory instantly, under some circumstances it may never actually perform the collection and that would be okay.
If you really need these kilobytes freed immediately, you might force GC to perform the clean-up just after the disposals, but it's a costly operation in general and may affect overall performance.
精彩评论