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 Hashtable. 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.
Related
I have a big solution with graphics, popups and animations. I have found out that I have a massive memory leak during page navigations.
Tries
I therefore tried with the first solution:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (App.RootFrame.CanGoBack)
App.RootFrame.RemoveBackEntry();
GC.Collect();
base.OnNavigatedTo(e);
}
This from several sources on MSDN and Stackoverflow, should remove the memory stored for the page. This was not the case and I am unsure if the MVVM structure of the code somehow keeps information stored. I then tried to implement deconstructors and force values to null when the event was fired like:
~SecondScreen()
{
In_Game_Crest = null;
currentViewModel = null;
}
This I did for all pages, popups and usercontrols. I then again went through the code using debug, and non of the pages deconstructor was ever fired. This has lead me on to try and use IDisposable and fiddeling around with the viewmodelLocator provided by MVVMLight, without any success.
Investigation
I have read the following addressing the issue:
StackOverFlow: Finalizer and Dispose
Finalize/Dispose pattern in C#
MSDN: Implementing a Dispose Method
MSDN: Implementing Finalize and Dispose to Clean Up Unmanaged Resources
Questions
But it has confused me more than it helped me. How should I implement the dispose and finalize methods for a page for my windows phone?
Since I'm using the MVVM structure should these methods be implemented in a ViewModel or behind the given page or both?
Examples for windows phones would be much appreciated.
Initial try with Dispose
I have read some more about the subject and found that the finalize maybe shouldn't be written? But I am still unsure. But based on this and the first MSDN link above, I tried the following:
private bool disposed = false;
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
currentView = null;
popup = null;
Image1 = null;
Image2 = null;
}
// Release unmanaged resources. If disposing is false,
// only the following code is executed.
this.Content = null;
// Note that this is not thread safe.
// Another thread could start disposing the object
// after the managed resources are disposed,
// but before the disposed flag is set to true.
// If thread safety is necessary, it must be
// implemented by the client.
}
disposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~FirstPage()
{
Dispose(false);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.Dispose();
base.OnNavigatedFrom(e);
}
But, but but this just made my memory increase by 23MB when I got to the second screen. This leads me to the question again, how and what should I try to implement, and WHY could the memory increase?
this = null, base.Dispose()
I have seen different implementations, either using this = null in the dispose function or using base.Dispose(). I figure that the latter can only be used if the class is IDisposable? Is this the way to go? If so how do I go about it?
Using Microsoft Profiler
So I used the profiler to verify that the FirstPage is not removed
From the above Figure it can be seen that the firstpage exists. In the comments I was told to look for the instances and reference to the elements. I therefore chose instances of firstpage and got:
Here it is confirmed that FirstPage is never destroyed. But I am stuck here, how should I interpret the data?
Hoping for some help.
It is not actually necessary to dispose when a user navigates away from a page, the performance implications of creating objects all over again is more than the memory load of having a page in the memory during when the application is alive.
You should take a decision between removing objects from the memory vis.a.vis recreating the same set of objects again.
Having said this you should be careful with the navigation model.
Memory problems might occur if you are creating objects every time the user is navigating to a page but not actually disposing when the user navigates away.
For this purpose I recommend fully understanding the PageBase and NavigationHelper or NavigationService class in your application.
You have mentioned that FirstPage is not removed from the memory during the life time of the app which according to me is ideal.
Place debug points in the potential places in your code where heavy objects might get created;
navigate a couple of times to different Pages, then come back.
Check the behavior then you might get a clear picture for yourself.
For all objects check that you manually invoke Dispose.
Dispose is a completely different concept than GarbageCollector, Dispose is just an contract that developers should adhere to by invoking it for releasing resources they perceive are no longer required to be maintained in the memory since garbage collection by the platform takes place at a indeterminate time.
In the sample you have posted I see that you are setting objects to null without actually disposing. Setting to null just changes the memory location that variable is pointing to.
It does not destroy the object immediately. an ideal dispose should be like below.
//Call on OnClosing or OnExit or similar context
protected override void Dispose(bool isDisposing)
{
if(isDisposing && !_isDisposed){
if(disposeableImage != null){
disposeableImage.Dispose();
disposeableImage = null;
}
}
}
So what I did to solve the page memory leak was using the answer at this question:
Remove Pages windows phone
There still exists some leak, which helped when removing the storyboards and eventhandlers, and adding them and removing them. But some memory is still there but no leak is occurring.
By default when you create a Win-Form a application, This is the code generated by visual studio to dispose the Form.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Is this enough?Or I should unregister all events so the controls will be ready to collected by the garbage collector?
if (disposing && (components != null))
{
myButton.OnClick-= MyFunction; //may be here!!
// ... all events used
components.Dispose();
}
The form must unregister all events from entities which will outlive the form. It doesn't matter if the form unregisters events from entities which have the same lifetime as the form. For whatever reason, the normal doctrine seems to be "don't worry about unregistering events, except when it matters". I would think it would be much cleaner to have all objects which subscribe to events unsubscribe them on Dispose, but unfortunately neither vb.net nor C# provides any even-remotely-clean way to accomplish this. With dependencies that implement IDisposable, it's possible to wrap construction in a routine which will add the newly-created item to a list of things to be cleaned up later. One can then perform all necessary cleanup by simply calling Dispose on everything in the list. Unfortunately, from the perspective of .net, there's no nice way to write a general-purpose routine which will simultaneously subscribe to an event and return an Action<>, IDisposable, or other such object which could be used to unsubscribe.
No, the garbage collector takes care of it. The event can never be raised anymore since the form instance was disposed which in turn disposed the button. There is a circular reference between the form and the button due to the event handler but the garbage collector has no trouble with them.
If this is the form that is a subject to often close and open operations, and use massive amount of events inside it, it's important to unregister all events. Cuase events consume resources definitely.
If this is a form that appears ones a while, or could even not appear ever, or it is, let's say, yuor application's MainForm, it's not important to unsubscribe from events.
What about a place where to do that, I would personally, unsubscribe inside, let's say inside Closing override and not in Dispose().
Which one is the right one?
This one:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
components.Dispose();
}
base.Dispose(disposing);
}
OR
This one:
~ ctlRemoteBuildContent1()
{
this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
}
I tried to toggle this 2 functions. When I did UserControl disposing, it didn't jump into the toggle line :/
If you clean up in a destructor, there's no guarantee as to when the destructor will be run. Objects with a destructor also require more work for the garbage collector to handle. It's preferable therefore to implement IDisposable, which is your first example.
Note that your code snippet does not fully implement the recommended IDisposable pattern. Please see this article for a good and complete explanation:
http://www.csharphelp.com/2010/02/c-garbage-collecting-destructors-versus-dispose/
In your code snippet, if for some reason components is null, you would not remove the event handler. The null check for components should only be done to protect the components.Dispose() call.
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.ctlRBContent1_GetBuildName -= _ctlBottom.GetBuildName;
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
The second bit of code is called by the finalizer, which means you won't be able to tell when this is called (depends on when the garbage collector runs). Ideally you want to free your resources as soon as possible, typically in a Dispose(). So use the dispose pattern here.
Why do you want to unsubscribe that event here? What does it contain?
Which one is the right one?
A slightly obnoxious answer is "both" ;-) ...
Ideally you want the tidying up to happen in the Dispose method so it can be performed as soon as possible, but in some situations it's important to also have the tidy up code called from the destructor as a back-up in case an object gets used without being disposed (...I guess it depends on how likely you think this could be!?)
The dispose pattern (mentioned in the other answers) provides a way of implementing this without code duplication between the dispose and destructor, and with the GC.SupressFinalize makes sure the object's garbage collection doesn't get held up unnecessarily if the tidy up has been done.
I have a C# service which listens to a queue for XML messages, receives them, processing them using XSLTs and writing them in the database.
It does process about 60K messages a day of about 1Mb each. The memory when is idle is going down to 100MB which is really good.
However recently I have started processing messages of 12 MB in size. It does blow the memory up and even when is idle it has memory of about 500MB. Any suggestions why this might be a problem? I don't think there is a memory leak as it would have surfaced after processing so many (60K messages of 1MB).
That looks perfectly fine. Why do you think this is a problem?
The garbage collector will eventually release the unused memory, but this doesn't mean this is going to happen as soon as your service is idle.
Raymond Chen has written a good article explaining the basic idea of garbage collection:
Everybody thinks about garbage collection the wrong way
However - but this is pure speculation with the information given in your questions - there might be memory leaks related to extension methods in your XSLT. Extension methods may lead to problems in case you recompile the stylesheet every time a new XML document is transformed. The fix is simple: Once compiled, cache the stylesheet.
SIR! PUT DOWN TASK MANAGER AND WALK AWAY. Seriously. Memory management in .NET is not tuned for smallest footprint. It is tuned for efficiency. It will hold onto memory rather than release it back to the system. Resist the temptation to babysit your memory unless there is an actual problem (OOM exceptions, system issues).
What measure are you using for memory? There are lots of possible measures, and none of them really mean "used memory". With virtual memory, sharing of images, etc. things are not simple.
even when is idle it has memory of about 500MB
Most processes (and I think this includes .NET) will not release memory back to the OS once allocated to the process. But if it is not in use it will be paged from physical memory allowing other processes to make use of it.
started processing messages of 12 MB in size
If an XML document is expanded into an object model (e.g. XmlDocument) it needs a lot more memory (lots of links to other nodes). Either look at a different model (both XDocument and XPathDocument are lighter weight) or, better, process the XML with XmlReader and thus never have a fully expanded object model.
First of all, add something to your system to allow you to manually invoke garbage collection for the purpose of investigation. The CLR will not necessarily return memory to the O/S unless it is in short supply. You should use this mechanism to manually invoke garbage collection when you have the system in a quiescent state so that you can see if the memory drops back down. (You should invoke GC.Collect(2) twice to ensure objects with finalizers are actually collected and not just finalized.)
If the memory goes down to the quiescent level after a full GC then you do not have a problem: simply that .NET is not being proactive at deallocating memory.
If the memory does not go down, then you have some kind of a leak. As your messages are large, it means their text representations are likely ending up on the Large Object Heap (LOH). This particular heap is not compacted which means that it is easier to leak this memory than with the other heaps.
One thing to watch out for is string interning: if you are manually interning strings this can cause LOH fragmentation.
Very hard to say what may be the problem. I've had success using Ants Memory Profiler when investigating memory issues.
Contrary to the thought I don't think there is a memory leak; I would profile the memory.
I would check your event handlers. If you're not careful detaching those when you're done, it seems like it's easy to create object references that won't be collected by GC.
I don't know that it's the greatest practice (since the onus of beginning and cancelling event handling should fall to the subscriber), but I've gone the route of implementing IDisposable and creating my events with an explicit delegate field instance. On disposal, the field can be set to null, which effectively detaches all subscriptions.
something like this:
public class Publisher
: IDisposable
{
private EventHandler _somethingHappened;
public event EventHandler SomethingHappened
{
add { _somethingHappened += value; }
remove { _somethingHappened -= value; }
}
protected void OnSomethingHappened(object sender, EventArgs e)
{
if (_somethingHappened != null)
_somethingHappened(sender, e);
}
public void Dispose()
{
_somethingHappened = null;
}
}
Barring that (I don't know how much control you have over the publisher), you might need to be careful to detach unneeded handlers on your subscriber:
public class Subscriber
: IDisposable
{
private Publisher _publisher;
public Publisher Publisher
{
get { return _publisher; }
set {
// Detach from the old reference
DetachEvents(_publisher);
_publisher = value;
// Attach to the new
AttachEvents(_publisher);
}
}
private void DetachEvents(Publisher publisher)
{
if (publisher != null)
{
publisher.SomethingHappened -= new EventHandler(publisher_SomethingHappened);
}
}
private void AttachEvents(Publisher publisher)
{
if (publisher != null)
{
publisher.SomethingHappened += new EventHandler(publisher_SomethingHappened);
}
}
void publisher_SomethingHappened(object sender, EventArgs e)
{
// DO STUFF
}
public void Dispose()
{
// Detach from reference
DetachEvents(Publisher);
}
}
I remember i was loading in images by streaming it from the net straight into a bitmap. close the stream, return the bitmap and held it in an image control.
I excepted when i did = loadPicture() the first bitmap would be freed like a smart pointer would do in C++. But it didnt and i consumed a lot of ram until i called dispose. So my question is.
How does the GC and Dispose able objects work in C#? and why isnt it implemented like a smart_ptr?
References are not smart pointers. Letting a reference-variable go out of scope, replacing it with another value, and/or setting it with null all do exactly nothing.
This is simply part of the CLI /GC design...
Gargage Collection (GC) will run when needed, and should clean up the managed memory used, and (if a finalizer is provided) any unmanaged resources too. But for deterministic cleanup: that is the entire purpose of IDisposable. It is your job to Dispose() such objects when you have finished with them - either via using, or by handing it to something else which assumes this responsibility (common, for example, with streams/readers etc).
using (StreamReader reader = new StreamReader(myfile)))
{
...
}
The GC kicks in when the runtime feels it is necessary.
The basic rule is: when you use an Disposable type (IDispose), then you (as the programmer) should release the resources used by that type as soon as possible, by calling Dispose when you do not longer need to use that type.
For instance, when you read a file, you close that file as soon as you've done reading it. (Calling close will also call dispose in this case).
You must call Dispose explicity on any object implementing IDisposable, otherwise your unmanaged resources will not be disposed. If you don't want to call it explicity, then you must override the Finalize method to call the Dispose method - that is why you will see this frequently:
class MyClass : IDisposable
{
...
~MyClass()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{ /* dispose managed stuff also */ }
/* but dispose unmanaged stuff always */
}
}
smart_ptr are reference counted. While this allows for deterministic release of their resources when they are no longer referenced by any code, they do have their problems of their own: assigning references always requires the counter to be updated, circular references fail to be released automatically causing memory leaks, the memory manager is invoked more often.
The GC in .NET is a sweeping collector. It starts at any time when it feels that memory should be released (usually triggered by some memory usage condition, but not deterministic) and starts by building a list of all live references in the system (including the ones in CPU registers, nested references etc.). This works since we are in a managed environment where you cannot do pointer arithmetic etc. - the system can track all references. After the list of live references has been built, it basically releases all memory not known to be used anymore. Of course, this is just the basic sketch, for efficiency and management of unmanaged resources there is more to it like object generations, finalizers, etc., but that is not important for the basic understanding of how it works.
The IDisposable interface is used to implement the disposable pattern, which helps when you are working with objects that should be disposed in a deterministic way. The pattern is so that Dispose() is called explicitly when the object is no longer needed, therefore releasing unmanaged resources or closing handles etc., but not releasing its memory. This will be done by the GC later on, but it does not matter that this happens later, because the deterministic release of resources has already been performed.