Prevent memory leaks in WPF - c#

Working with WinForms you have to free memory after using gdi objects, event handlers, objects from native code, etc.
In WinForms I used to remove for example event handlers in the dispose method.
What is the best workaround to prevent memory leaks in Wpf? Is it the same as in Winforms using Dispose pattern? At all, do I have to care about event handlers, gdi objects in Wpf? What about the runtime created resources(Brushes, etc)?

This blog post lists the most common situations that cause memory leaks in WPF applications.
Event handlers to objects in parent windows
Registering to events from static objects
Using timers
Data binding
Changing the Text property of a text box
It also describes how to fix these common issues.
Another good approach is to develop an app while following the standard guidelines and then use some kind of profiler to determine any memory leaks or performance bottlenecks.

From MSDN: Any WPF framework-level element (those objects deriving from either FrameworkElement or FrameworkContentElement) has three common lifetime events: Initialized, Loaded, and Unloaded.
.....
Unloaded is raised last and is initiated by either the presentation source or the visual parent being removed. When Unloaded is raised and handled, the element that is the event source parent (as determined by Parent property) or any given element upwards in the logical or visual trees may have already been unset, meaning that data binding, resource references, and styles may not be set to their normal or last known run-time value.

Some helpful links on WPF resource dictionary leaks:
DynamicResource\StaticResource cause memory leaks
Memory leak problem with ResourceDictionary and MergedDictionaries

Watch out for events: it's very easy to miss something, because all references from the delegate will exist until the delegate lives. I suggest to use weak event pattern when it's possible. Actually Microsoft uses it in their Prism framework.
http://msdn.microsoft.com/en-us/library/aa970850.aspx
Also check out an issue that I was catched by many times when learning WPF http://support.microsoft.com/kb/938416/en-us

Related

How to create a Weak Referenced Event Handler?

I am doing research on how to properly create a weak referenced event handler. Since WPF has already a solution for avoiding memory leaks with events, I decompiled the "WeakEventManager" class and spent some time on analysing it.
As I found out, the "WeakEventManager" class relies on creating and storing a weak reference to the target object as well as to the event handler delegate. Here are some code segments:
this._list.Add(new WeakEventManager.Listener(target, handler));
public Listener(object target, Delegate handler)
{
this._target = new WeakReference(target);
this._handler = new WeakReference((object) handler);
}
I am asking myself if this simple solution would already be working or did I overlook an important aspect, since most other solutions I found on the Internet are complex and hard to understand. The best solution I could find so far
uses an unbound delegate. That is some kind of wrapper delegate that takes the event handler and event subscriber instance as a parameter (yes, it requires the event subscriber object to be passed in during delegate invocation).
You can find this great article here:
http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx#commentstart
The "WeakEventManager" class doesnt't rely on knowing the subscriber class or any additional information. Beyond that it also works with anonymous delegates. Why do developers spent so much time on writing a solution that is not only working but also convenient to use, if a solution only requires them to store a weak reference to the delegate? What's the catch?
Update: Because someone downvoted this question (may be it is a little bit unspecific), I want to give a more precise question:
Is that source code above all it takes to create a working weak event handler? If not, what is missing?
did I overlook an important aspect
Yes, an important one. You traded one "leak" for another. Instead of preventing the event subscriber objects from getting garbage collected, you now prevent WeakReference objects from getting collected. You are not ahead.
What is also required is a mechanism to get those stale WeakReferences cleaned-up. You don't need them anymore when their IsAlive property returns false, you then remove it from _list. But you have to check that separately, some code needs to take care of that. An obvious choice is to check when an event is added or when it is fired. But that isn't enough, since client code only ever adds at initialization and you can't get a guarantee that the event is consistently fired.
So some kind of scheme is required to do it later. Anything is possible and nothing is quite ideal because it is a lot of busy-work with often not getting anything done. Making the right choice is important. And that certainly includes not doing this at all, it tends to be a band-aid over a design problem.
The idea behind the WeakEventManager is that it keeps a list of weak references to the target object of the events and a list of handlers it must call, but does not "tie them together" (as directly subscribing to events typically does), allowing the target to be garbage collected (and periodically checked so that the "subscribed" delegate list is emptied accordingly when the source is garbage collected).
This, which sounds easy, requires a lot of plumbing code, and that's all the WeakEventManager does (do the plumbing for you in an easy to use manner).
If you are cloning out WeakEventManager to your own implementation (or using the built-in) and it does that, then yes, that's all you need to do. If that's not what you are asking, then the question is unclear to me.
Is that source code above all it takes to create a working weak event handler? If not, what is missing?
That is the most important bit, the rest of the Listener class is important as well, not to mention the manual plumbing required to support this non-delegate event handler.
For instance check out ListenerList.DeliverEvent which is a bit more involved than the usual Invoke call.
Basically the normal event system assumes strong references so in order to use WeakReference you end up having to add a lot of the translation logic yourself as well as deciding how to handle events that never fire due to using WeakReference.

.Net Winform Controls (MenuItem, ToolBarButon, ContextMenu, Splitter etc ) not releasing my User Control. A Memory leak issue

I have a C# WinForm User control made up of many child user controls such as MenuItem, ToolbarButton, ContextMenu, Splitter, Panel..etc..I open and close this user control many times in a ActiveX container. I see its it leaks memory every time it is open and close. I called GC.Collect in the dispose of this control and found that it leaks less memory now. but still it leaks.
I have also called the dispose on all other child controls MenuItem, ToolbarButton, ContextMenu, Splitter, Panel..etc in Dispose method of User Control but still i see that my User control is not GCed.
Please find the image from .Net profiler..you can copy the link of image in other tab of browser to see it large aaTrendControl is the name of my user control.
Find the image when I click on one child control instance in
Why MenuItem and ToolbarButton control are not releasing my UserControl even when I Dispose them..Is anything I am missing.
Simply calling GC.Collect will not release everything that went out of scope in one go. Garbage collection is allot more complicated. There is a concept of generations. Referring to objects that in turn refer to objects place them in different generations, and one call to GC.Collect will most likely only remove the last generations in one cycle. Calling it multiple times will also have little effect. If there's not much to do it may just ignore the call and return with "I'm done".
I recommend you read the excellent book Under the hood of .Net Memory Management. It's a freely downloadable PDF with allot of details on what's going on.
From your story, it is likely you are creating many "handles". Every control on a form has a so-called handle. These are native windows resources, that need to be "pinned" in order for windows to send messages to them (mouse-over, click etc...). Pinned objects are even more complicated because the GC cannot simply move them to another part of memory when defragmenting, so excessive allocation of controls can cause fragmentation problems. In the old days (before windows XP) there used to be a hard limit on the number of handles that a process would be allowed to allocate.
You may want to consider using GDI+ a little more to save out extra controls. For example, when creating excel-like grids, it is custom to draw the whole grid on one canvas, and only when the user clicks (or focuses) on a single cell, overlay it with a textbox or dropdown control in-place. Creating separate controls for each cell would have an enormous overhead, even on a modern computer.
It's good practice to re-use controls instead of disposing them and recreating them. Reusing controls will have a huge positive impact on performance. This because of the fact that visual controls require a context switch between your process and the OS in order to acquire a handle. Unfortunately I don't know of a good book on windows forms. I learned most of the details from my old Delphi 2 books, almost two decades ago. I might be outdated on some details, but the essential basic concepts in WinForms have not changed since then. Even when you work with .Net, an old book on the native Windows API's should help you get an idea on what's going on under the hood.
.Net will take care of the memory management saving you quite some headache, but fragmentation can cause problems, which can be overcome by reusing visual objects instead of disposing them. If you really need to call GC.Collect in your code, it usually implies you are doing something else wrong (exceptions exist though).

Advanced debugging advice in WPF GarbageCollection

Situation
We are running a large WPF application which does not release memory for quite some time. It is not a real memory leak, as the memory will be released eventually. I know that normally, this would not be considered to be a problem. Unfortunately it becomes a performance issue in conjunction with the WPF commanding infrastructure. See below for a more detailed description.
Findings
We have automated tests, that perform typical use cases. Some cases are working fine and are releasing the memory in time. Others are hogging the memory until the client is minimized, a new Window is opened or some other conditions occur that triggers a Gen2 collection.
• With ANTS we see, that the objects do not have a GC Root, but a lot of references to other objects that require finalization.
• WinDbg does not show any objects to be ready for finalization.
• Running several GC.Collect(), GC.WaitForPendingFinalizers() completely frees the memory.
• We know which UI action causes the high memory condition, but we could not identify any suspicious code.
Question
We would appreciate any advice on debugging such a problem.
WPF CommandManager Background
The WPF CommandManager holds private collection of WeakReferences (_requerySuggestedHandlers) for raising the CanExecuteChanged Event. Handling CanExecuteChanged is quite costly (especially finding the EventRoute for CanExecute, which apparently is a RoutedEvent). Anytime the CommandManager feels like requerying if commands can be executed, it iterates through this collection and calls the CanExecuteChanged event on the respective command sources.
The WeakReferences are not removed from that collection as long as there is a GC handle for the referenced object. While the object has not been collected, the CommandHelper keeps processing CanExecute events for these elements (ButtonBase or MenuItems). In case there is a lot of garbage (as in our case), this can result in an extremely large number of calls the CanExecute event handlers, which causes the application to be really laggy.
I have the same issue with one of my applications. On every opening of a window I call:
GC.GetTotalMemory(true);
This will force GC to clean the memory immediately without waiting. You can read more about this method here:
http://msdn.microsoft.com/en-us/library/system.gc.gettotalmemory.aspx
About the problem with the calls to CanExecute, I try to avoid them because of the same performance problems. Instead, I use properties in my view model and bind the IsEnabled property of the visual elements from XAML to the properties from the view model. In this way, the overall performance is improved and the CanExecute calls are gone.
I hope this will help.
Try CLRProfiler, here's the downloading link. It shows the event handlers allocated, disposed and survived. I am sure you can trace to the root cause by using this tool.
The book Advanced .NET Debugging lists some good tools for debugging, you can read it for some help.

When to use Weak Events?

I was refering MSDN tutorial on weak events. I understood the basics. I am working on a non-WPF project and my class is exposing certain events. My question is that does the weak events
completely replace old event pattern? Is it good to use it every classes that is exposing events? What are the side effects of using weak events liberally?
Based on the reading I have done, there does not appear to be any specific negatives to using WeakEvents, except for the fact that it is more verbose to do so. Additionally, you should be able, in most cases, to manually unregister from events when you no longer need them. In some cases, this won't be possible. For example, the MSDN page you reference mentions when you should use WeakEvents:
http://msdn.microsoft.com/en-us/library/aa970850.aspx
Certain scenarios inherently lend themselves to the application of the weak event pattern. One such scenario is data binding. In data binding, it is common for the source object to be completely independent of the listener object, which is a target of a binding. Many aspects of WPF data binding already have the weak event pattern applied in how the events are implemented.
The only person who has presented any type of negative to them is this blog:
http://blog.catenalogic.com/post/2011/11/23/A-weak-event-listener-for-WPF-Silverlight-and-Windows-Phone-7.aspx
There are a few downsides about using a weak event listeners in general:
It’s notation is ugly, the “original” .NET way looks way better
You have to name the event by string, that sucks (if you know a better way, contact me!)
It can only handle events with a handler of EventHandler
You become a lazy developer not caring about subscriptions
Essentially, they should be used for events that your objects will subscribe to for the entire length of their existence, and only disconnect from when the objects are disposed. For everything else, using the traditional events and registering/unregistering the events manually is preferred.
There are two issues that must be considered with weak events:
Weak events allow subscribers to subscribe to events (messages) even without knowing the identity of the class raising the event. In some cases that may be desired even necessary. However, in some cases that can introduce unnecessary complexity and a level of indirection that makes the code harder to manage or control at run time.
The major downside of using weak events is that it may encourage developers to neglect the part where they unsubscribe from events (messages). In that case event handlers may be invoked even after the subscribers "go out of scope". Consider a subscriber that does not explicitly unsubscribe and that becomes garbage collectable but was not yet garbage collected. The weak event manager will not be able to detect that state and because of that it will still call the event handler of that subscriber. This can lead to all kind of unexpected side effects.
See more details at The Weak Event Pattern is Dangerous.
See this source code that illustrates this issue using the MvvMCross messaging plugin as a weak event manager.
When to use weak events?
From MSDN
Listening for events can lead to memory leaks
So you should use weak events with the purpose of avoiding those leaks
Is it good to use it every classes that is exposing events? What are the side effects of using weak events liberally?
See Why is the implementation of events in C# not using a weak event pattern by default?. Leaking from "strong" events is not that usual, weak events come with a performance cost and have a semantic difference that may not be desired in every context, misuse of a weak reference can cause the event to intermittently not to fire (in contrast to misusing a normal event causing a memory leak)
Example memory leak that could be avoided
Static classes and Singletons are villains when talking about memory leaks, when they acquire a reference to some other object they will prevent the object from being garbage collected, and thus, leak the object forthe lifespan of the application, here is an example where I met with the need for a weak reference to avoid a memory leak
First of all, weak events are not always necessary, like others have been saying only when the source object outlive the subscriber. If that is the case, then yes, you should use it, this is what people call The Weak Event Pattern.
The side effects are just that you will have to write more code. Microsoft provides the WeakEventManager class and in WPF exist some specific implementations, but you can create your own inheriting from the base WeakEventManager.
The way it works is by using weak references from the source object to the listener so this relationship doesn’t stop the GC from collecting these objects. For some specific applications this can solve a lot of performance issues.

How to clean up memory used by many user controls

I have many user controls where I add only one of them each in a panel but first clear the panel from the previous one.
I create a new instance of the user control when I want to add it in the panel, and Dispose() the other user controls and set all the references to null to allow the garbage collector to delete them.
For example:
// Declare the variables globally
ViewBasicInformation control1 = null;
AddBasicInformation control2 = null;
// Code inside Button
Panel.Controls.Clear();
control1.Dispose();
control1 = null;
control2 = new AddBasicInformation();
Panel.Controls.Add(control2);
However my memory usage keeps increasing, how do I release this memory?
And for more information ... Every user control consumes a class that makes a connection to a smart card and executes some commands to read and write to the card.
I also have a backgroundworker that detects when the card is inserted or ejected.
The .NET runtime uses garbage collection - I urge you not to manage memory yourself.
I would expect memory to go up initially - if it never goes down, you have dangling references somewhere. Chances are you are subscribing to events and when the objects that have been subscribed are no longer needed you do not unsubscribe from these events. This is the most common cause of memory leaks in .NET applications (though dealing with unmanaged code is a close second).
Make sure you unsubscribe from any control event that you have subscribed to before you clear out the reference to it.
Regardless of the garbage collector being quite clever about when it has to run and when it doesn't need to, there are a number of error sources where you effectively get yourself into memory leaks based on event handling and different lifetimes of objects. This has been a subject on SO before (e.g. here) and I have written a little bit about some mistakes we did on one project that was the cause of memory leaks here: Do you think your Windows.Forms Application has no memory leaks?

Categories