I'm working on new WPF application. And I'm just wondering do I have to dispose or clear memory in any way in Views or View Models?
I only found information, that I should do it when using com ports or any external devices.
This is a very general question, so it is hard to provide a specific answer. .NET applications are garbage collected, so in general things are cleaned up once you no longer reference them anywhere.
Objects that Need Cleanup
There are certain things that the garbage collector will not clean up for one reason or another. In the vast majority of these cases, the class you are working with will implement the IDisposable interface. The most common things that I run into that are disposable are streams and stream-related classes. However, it is a good idea to check anytime you are using something you are unsure about.
So when it comes to views and view models in WPF, the same rules apply. If you are using something that implements IDisposable, then you need to either call Dispose on it when you are done, or wrap the creation of the object in a using block if it makes sense for the use case.
In some cases, a viewmodel might own an instance of a disposable object. In such a case, the viewmodel should itself implement IDisposable, and ensure it disposes the object within its own Dispose method. You will then need to call Dispose on the viewmodel when you are done with it.
Events
A common source of memory leaks in .NET applications are event handlers. Once an application starts to have some complexity to it, you might find that a temporary object (like some viewmodels) will want to register for events with things that have a longer lifespan (such as a service or persistent utility). Registering an event handler using the += operator creates a hidden reference from the event sending object to the event handling object. You will need to remove these handlers using the -= operator to allow the garbage collector to cleanup the handler and the object that owns it.
If you find yourself in a situation where you do not have a valid place to ensure an event is unregistered, consider using a WeakEventManager to add the handler instead of the += operator. This allows an object to handle events without the event sender having an explicit reference to the handling object. However, there is a very small amount of additional performance and memory overhead registering for events this way, so I would not recommend blindly switching all of your event handlers to weak events. Use it just where you need to.
Keep in mind that there are plenty of cases where not unregistering an event is ok and will not cause any memory leak. This is usually true when both the event sender and the event handler have the same life cycle, as is usually the case with a view and its associated view model. In such a case, it is fine for the view to register for events on the viewmodel and never unregister. As long as both the view and viewmodel stop being referenced by anything, they will get cleaned up regardless of the event that links them together.
Summary
There are no hard rules on whether views and viewmodels need any special handling to clean them up. If they are making use of a feature that requires special cleanup, then you will have to deal with that in whatever way is appropriate.
If you are not using any disposable objects, or other things that need explicit cleanup, then all you have to worry about is removing references to your views and viewmodels when you no longer need them.
If you want more technical information about the garbage collector, take a look at this article. Having an understanding of how it works may help you better understand when and how to clean things up.
Related
I understand the Weak Reference and the Weak Event Pattern.
One place where the weak event pattern is used is in DataBinding between Controls and DataModel.
During the process of DataBinding, if the DataModel support INotifyPropertyChange, the Control will ask the DataModel to advise him on change through the event.
Without weak event the DataModel would have kept a hard ref on the control. Due to that reference, the control could not be marked as available for GC at the same time as the window become available to be GC.
Microsoft decided to use weak reference to solve this issue.
I wonder if other alternatives like the proposed one would not have been better ?
Alternative: Implement IDisposable on Window with code that pass its children UiElements in order to ask them to remove their DataBinding to the DataModel ?
What would have been wrong with that solution ?
There's one fundamental advantage in using weak events: the task to unbind the Control from the DataModel is left to the garbage collector itself. The garbage collector typically runs in a low-priority thread that is only activated when the system is idle or when there's need to free up memory, so it doesn't slow down other activities. By contrast, having IDisposable detach the Control from the DataModels means that if you manually dispose of the Control, the unbinding has to take place in the regular caller's thread.
Another aspect (and this is mandated by the MVC pattern) is to leave the model independent from the view. If you think of object lifetime as a dependency, weak references are exactly what it takes to keep the models independent, since you don't have to rely on the controls' cooperation to release the bindings.
I have read a lot about this topic, and still I don't have the clear path how to proceed. Can anyone point to some resource (or explain) that shows in detailed step how to find the reason why some objects dctor is not called.
basically my logic for testing leak is this (WPF application):
create some View/ViewModel
close the View
call GC.Collect()
After a few seconds a dctor on ViewModel class is normally called, but on my application is never called. I would like to know which object is holding a reference to it at that time, since in my opinion it is the way to find the cause of memory leak.
This classes do not user any unmanaged resources, and do not have IDisposable implemented, which means there is no SupressFinalize call to prevent desctructor execution.
Edit: ViewModel is retrieved through a Static property on ViewModelLocator, and is added List. This is required by TabControl, which needs collection of view models to bind to. View and ViewModel are connected through DataTemplate.
First, search for non-unsubscribed event handlers and static references pointing to your ViewModel, even indirectly. Since you're in a WPF application, also ensure that you don't use DependencyPropertyDescriptor.AddValueChanged which is known to cause leaks by using static references.
If you can't find anything manually, use the awesome (this is my opinion, I'm in no way affiliated with them) SciTech .NET Memory Profiler. You can see for every object all the references it holds and which other objects are holding a reference to it, in a nice graph
view. It also warns you for common memory problems.
EDIT:
ViewModel is retrieved through a Static property on ViewModelLocator
Search no longer, you have your leak. Static references prevent objects from being garbage collected. Remove the static reference or wrap it in a WeakReference.
I understand it is best practise to call Dispose() on instances of Pen and Brush, except if they've been set to the system-predefined values (eg. System.Drawing.Brushes, System.Drawing.Pens or System.Drawing.SystemBrushes)
Trying to dispose a system-defined resource results in an exception being thrown.
It doesn't appear to be obvious how you can detect (apart from wrapping the Dispose() call in a try/catch) whether one of these resources is referencing a system-defined or user-defined value.
This is an old question I know, but I've been doing some research into resource leaks involving GDI objects, and almost every statement in the accepted answer is false. In the interests of accuracy for later readers who find this question via a search, as I did:
There is no requirement to call Dispose.
This statement is misleading. Though technically you can get away with not calling Dispose, it is an extremely poor practice to not dispose of a brush or pen that you own once you're done with it.
The reason is: there is a hard limit (set to ten thousand by default, though that can be increased via registry hacks) of the number of GDI objects that can be outstanding in a process -- not application domain, note -- and the garbage collector might not get around to finalizing resources faster than they are being leaked. Managed memory allocations produce collection pressure but there is no corresponding finalization pressure.
The purpose of garbage collection is to eliminate these kinds of requirements.
It is not. The purpose of garbage collection is to emulate an environment with arbitrarily much memory.
One of the main purposes of IDisposable is to allow a class to clean up unmanaged resources in resource-limited environments.
This is correct.
If you do not call the Dispose() method, the unmanaged resources of the class will be cleaned up once the object is finialized and disposed during garbage collection.
This is sometimes correct; it is correct for GDI objects. It is a good practice for classes which hold on to unmanaged resources to implement finalization semantics as a backstop; an extra layer of protection for people who follow the bad advice given in the accepted answer. You should not rely on finalizers to save you from your mistakes; you should dispose of your resources.
You should only rely on a finalizer to deal with crazy exceptional situations. Consider for example:
Brush myBrush = MakeMeABrush();
DoSomethingWithBrush(myBrush);
myBrush.Dispose();
Suppose a thread abort exception is thrown after the allocation of the brush but before the assignment to myBrush. No combination of try-catch-finally will enable you to clean up that brush via Dispose; you'll have to rely upon the finalizer. That's what the finalizer is for: the completely crazy situations where you cannot dispose yourself. It is not an excuse to be sloppy.
If you "must" call dispose and you do not know if the brush instance is a "system-" or a "normal-" brush then you will have to use a try...catch block.
Though this is again, technically correct, it misses the point completely. If you are in a situation where you do not know whether or not you own the brush then you have a bug in your program design. Do not paper over your bugs with a try-catch block! Fix the bug!
This situation is common to all explicitly-managed resources: the entity which provides the resource and the entity which consumes the resource are responsible for clearly documenting which of the two owns cleaning up the resource. If you don't know whether you own the brush that you've been given or not then someone isn't doing a task they were responsible to do, namely, preventing that situation from ever arising.
If the contract you decide upon is that the entity which provides the resource is responsible for cleaning it up later then your consumer shouldn't be disposing of the brush at all, because that is breaking the contract; the producer will clean that up if it needs to.
If the contract you decide upon is that both the producer and consumer are going to free the resource, then the consumer must call Clone on every brush passed in to ensure that they have a safely disposable resource, and that the producer continues to own a valid resource as well.
If, most likely, the contract you decide upon is that the entity which is consuming the resource is responsible for cleaning it up later then the provider is required to always hand you a brush that you can safely dispose, and is required to not dispose the resource itself. Since the provider knows whether they made the brush themselves or got it from the system, the provider must call Clone() on system brushes to obtain a brush that can be safely disposed, and then pass that to the consumer.
But the contract "no one cleans it up and we hope for the best" is a pretty poor contract.
It is not needed to call Dispose() on SystemBrushes and SystemPens because the GDI+ Library will take care of these resources.
This explanation is an explanation that doesn't actually explain anything. The reason why it is illegal to dispose of one of these brushes is because the lifetime of the brush is equal to the lifetime of the appdomain.
The Remarks section of the class will make note of if there is a requirement to call the Dispose method.
This statement is false. You should make the assumption that it is always necessary to Dispose an IDisposable resource unless you have good reason to believe otherwise. The absence of a line in the documentation is not evidence that disposing is unnecessary.
To end on a positive note:
If I have a graphic-intensive application or class then I will cache instances of the pens and brushes I need. I use them throughout the life of the application or class.
This is a good practice. If the number of brushes and pens created is relatively small and the same ones are being used over and over again, then it makes good sense to cache them permanently. Since their lifetimes are to the end of the program there is no need to dispose them. In this case we are not disposing the garbage because it's not garbage; it's useful. GDI objects that are not cached should of course still be disposed. Again, pursuing a caching strategy is not an excuse to engage in poor practices.
When you are finished with a Graphics object that you create, you must dispose of it by calling its Dispose method. (This rule is true for many different GDI+ objects.) Don't keep it around for a rainy day because it won't be valid later. You must, must, must dispose of it when you are finished with it. If you don't, it could result in image corruption, memory usage issues, or worse yet, international armed conflict. So, please dispose of all Graphics objects properly.
If you create a Graphics object within an event, you really need to dispose of it before exiting that event handler. There is no guarantee that the Graphics object will still be valid in a later event. Besides, it's easy to re-create another Graphics object at any time.
Got from here
http://msdn.microsoft.com/en-us/library/orm-9780596518431-01-18.aspx
First of all, you always should Dispose of brushes when you can and not leave it up to the garbage collector. While GDI will eventually get around to taking care of that stuff (assuming the library gets shut down properly), there's no telling when that may be. In fact, my understanding is that brush handles stick around for the long-term. Over the course of a long-running application, you're looking at a de facto memory leak. Sure, in a small application that won't run for long, or in one that only rarely creates brushes, you can let the system handle it, but that strikes me as sloppy.
As a general rule, whenever I create a brush I do so in a using statement. That automatically calls dispose on the brush without having to worry about it. As an added bonus, since you create the brush inside the statement you know that it's not a predefined brush. Any time you create and use a non-predefined brush, wrap the block in a using and you don't have to worry about it at all. In fact, you don't even need to explicitly call Dispose, since the block will do so even in the case of an exception.
Short answer is,.. if you create it, either delegate responsibility to clean up or clean the objects up yourselves. You can create GDI resource "leaks" by letting things hang in the garbage collector. They may eventually be cleaned up, but they are not doing any good hanging there. i.e. if you don't call "close" or Dispose on opened files, the file's remain locked until the GC "gets around to it"
I could be wrong but I think you can assume that the lifetime (and the disposal) of the predefined brushes and pens is not your app's responsibility and will be handled by the system.
In short: don't call Dispose on the predefined stuff. :)
Only thing come in mind is to have a practice do not use System pens/brushes as parameters to methods.
Just for completeness, using Reflector I see that the System.Drawing.Pen and System.Drawing.SolidBrush classes have a private field named 'immutable'.
This field appears to be set to true when the object refers to a system-defined resource, so you could use reflection to carefully check the value of this field to decide whether to call Dispose() on it.
There is no requirement to call Dispose. The purpose of garbage collection is to eliminate these kinds of requirements.
One of the main purposes of IDisposable is to allow a class to clean up unmanaged resources in resource-limited environments. If you do not call the dispose method, the unmanaged resouces of the class will be cleaned up once the object is finialized and disposed during garbage collection.
If you "must" call dispose and you do not know if the brush instance is a "system-" or a "normal-" brush then you will have to use a try...catch block.
It is not needed to call dispose on SystemBrushes and SystemPens because the GDI+ Library will take care of these resources.
Okay to dispose of SystemFonts and SystemIcons.
The Remarks section of the class will make note of if there is a requirement to call the Dispose method. If the Remarks section recommends to call the Dispose method, then I will do it.
In general, I do not call dispose on pens and brushes. If I have a graphic-intensive application or class then I will cache instances of the pens and brushes I need. I use them throughout the life of the application or class. If I didn't do this then graphics painting performance will suffer trying to create and dispose all those ojects so many times and so frequently. (Hm...now that I think about it, performance is probably why we cannot dispose of SystemBrushes and SystemPens, yet can dispose of SystemFonts and SystemIcons. Even the framework caches SystemBrushes and SystemPens.)
I am using several Blend behaviors and triggers on a silverlight control. I am wondering if there is any mechanism for automatically detaching or ensuring that OnDetaching() is called for a behavior or trigger when the control is no longer being used (i.e. removed from the visual tree).
My problem is that there is a managed memory leak with the control because of one of the behaviors. The behavior subscribes to an event on some long-lived object in the OnAttached() override and should be unsubscribing from that event in the OnDetaching() override so that it can become a candidate for garbage collection. However, OnDetaching() never seems to be getting called when I remove the control from the visual tree... the only way I can get it to happen is by explicitly detaching the problematic behaviors BEFORE removing the control and then it is properly garbage collected.
Right now my only solution was to create a public method in the code-behind for the control that can go through and detach any known behaviors that would cause garbage collection problems. It would be up to the client code to know to call this before removing the control from the panel. I don't really like this approach, so I am looking for some automatic way of doing this that I am overlooking or a better suggestion.
public void DetachBehaviors()
{
foreach (var behavior in Interaction.GetBehaviors(this.LayoutRoot))
{
behavior.Detach();
}
//continue detaching all known problematic behaviors on the control....
}
What you really need in this case is not some way to automatically detach but to ensure that the reference held by the long lived object does not keep the behaviour (and therefore everything else it has a reference to) from being garbage collected.
This is acheived by implementing a Mediator pattern. The concept is that you don't give the long-lived object a delegate with a reference to your Behaviour, instead you create a Mediator class as a go-between. The mediator attaches to the long-lived objects event and holds a WeakReference to the behaviour. When the long-lived object fires the event the mediator checks that the WeakReference is still alive, if so calls a method on it to pass on the event. If when the event occurs the mediator finds that the WeakReference is no longer alive it detaches its event handler from the long lived object.
Hence there is nothing stopping the behaviour and everything else involved from being garbage collected all thats left is a very small mediator instance with a dead reference still attached to the long-lived object. Since these mediators are tiny they don't represent a real problem and even those will disappear the next time the event fires.
Fortunately you don't have to build this stuff yourself others have already done it. It is called the WeakEventListener. This blog: Highlighting a "weak" contribution; Enhancements make preventing memory leaks with WeakEventListener even easier! has an excellent set of links on the subject.
Joost van Schaik offers an alternative way to clean up references from attached behaviors, while avoiding the problem with the memory leak. It depends on doing the cleanup work using delegates of the Loaded and Unloaded events of the AssociatedObject.
He also offers a code-snippet for generating stubs for attached behaviors.
I have a WPF application based on PRISM that utilizes the MVVM pattern.
I have noticed that occasionally my view models, views and everything connected to them will hang around long after their intended lifespan.
One leak involved subscribing to CollectionChanged on a collection belonging to an injected service, another involved not calling the Stop method on a DispatcherTimer, and yet another required a collection be cleared of it's items.
I feel using a CompositePresentationEvent is probably preferable to subscribing to CollectionChanged, but in the other scenarios I am leaning towards implementing IDisposable and have the views call the Dispose method on the view models.
But then something needs to tell the view when to call Dispose on the view model, which gets even less attractive when the complexity of the views increase, and they start including child views.
What do you think is the best approach to handling view models, to ensure they don't leak memory?
Thanks in advance
Ian
I can tell you that I've experienced 100% of the pain you have experienced. We are memory leak brothers, I think.
Unfortunately the only thing I've figured out to do here is something very similar to what you are thinking.
What we've done is create an attached property that a view can apply to itself to bind a handler to the ViewModel:
<UserControl ...
common:LifecycleManagement.CloseHandler="{Binding CloseAction}">
...
</UserControl>
Then our ViewModel just has a method on it of type Action:
public MyVM : ViewModel
{
public Action CloseAction
{
get { return CloseActionInternal; }
}
private void CloseActionInternal()
{
//TODO: stop timers, cleanup, etc;
}
}
When my close method fires (we have a few ways to do this... it's a TabControl UI with "X" on the tab headers, that kind of thing), I simply check to see if this view has registered itself with the AttachedProperty. If so, I call the method referenced there.
It's a pretty roundabout way of simply checking to see if the DataContext of a View is an IDisposable, but it felt better at the time. The problem with checking the DataContext is you might have sub view models that also need this control. You'd either have to make sure your viewmodels chain forward this dispose call or check all of the views in the graph and see if their datacontexts are IDisposable (ugh).
I sort of feel like there is something missing here. There are a few other frameworks that attempt to mitigate this scenario in other ways. You might take a look at Caliburn. It has a system for handling this where a ViewModel is aware of all sub view models and this enables it to automatically chain things forward. In particular, there is an interface called ISupportCustomShutdown (I think that's what it's called) that helps mitigate this problem.
The best thing I've done, however, is make sure and use good memory leak tools like Redgate Memory Profiler that help you visualize the object graph and find the root object. If you were able to identify that DispatchTimer issue, I imagine you are already doing this.
Edit: I forgot one important thing. There is a potential memory leak caused by one of the event handlers in DelegateCommand. Here's a thread about it on Codeplex that explains it. http://compositewpf.codeplex.com/WorkItem/View.aspx?WorkItemId=4065
The latest version of the Prism (v2.1) has this fixed. (http://www.microsoft.com/downloads/details.aspx?FamilyID=387c7a59-b217-4318-ad1b-cbc2ea453f40&displaylang=en).
My findings so far...
In addition to PRISM, Unity, WPF and MVVM we are also using Entity Framework and the Xceed data grid. Memory profiling was done using dotTrace.
I ended up implementing IDisposable on a base class for my view models with the Dispose(bool) method being declared virtual allowing sub classes the chance to clean up as well.
As each view model in our application gets a child container from Unity we dispose it as well, in our case this ensure that EF's ObjectContext went out of scope. This was our major source of memory leaks.
The view model is disposed within an explicit CloseView(UserControl) method on a base controller class. It looks for an IDisposable on the DataContext of the view and calls Dispose on it.
The Xceed data grid seems to be causing a fair share of the leaks, especially in long running views. Any view that refreshes the data grid's ItemSource by assiging a new collection should call Clear() on the existing collection before assigning the new one.
Be careful with Entity Framework and avoid any long running object contexts. It's very unforgiving when it comes to large collections, even though you have removed the collection if tracking is turned on, it will hold a reference to every item in the collection even though your no longer hanging on to them.
If you don't need to update the entity retrieve it with MergeOption.NoTracking, especially in long lived views that bind to collections.
Avoid views with a long life, don't hold onto them within a region when they are not visibile, this will cause you grief especially if they refresh their data at regular intervals when they are visible.
When using CellContentTemplates on the Xceed Column don't use dynamic resources as the resource will hold a reference to the cell, which in turn keep the entire view alive.
When using CellEditor on the Xceed Column and the resource is stored in an external resource dictionary add x:Shared="False" to the resource containing the CellEditor, once again the resource will hold a reference to the cell, using x:Shared="False" ensures you get a fresh copy each time, with the old one being removed correctly.
Be careful when binding the DelegateCommand to items within the Exceed data grid, if you have a case such as a delete button on the row which binds to a command, be sure to clear the collection containing the ItemsSource before closing the view. If you're refreshing the collection you also need to reinitialize the command as well as the command will hold a reference to each row.