Silverlight control not being garbage collected because of command - silverlight

My control is being kept alive because of command it is bound to. How can I break this reference? This is causing a major memory leak in my application. The control is inside of a DataTemplate so I have no direct access to it.
Here is my ANTS memory profile:
How on earth do I break this connection?

Though I incorporated WeakEventListener, I discovered that my problem was with the control I was using to wrap up my images. I was hooking it up to DownloadProgress, ImageOpened, and ImageFailed events and never unhooked them. My thinking was that nothing else in my code was touching the BitmapImage objects so they would be garbage collected with the control. This, it sees, is not the case. The BitmapImage objects were referenced by a static member (and therefore a GC root) deep within Microsoft's code called "ManagedPeerTable.PeggedManagedPeersWithRefs". It was so deep that a Google search returned only five results for it. Now I suppose there will be six.

Related

WPF View leak - invisible, but still rendered in the background

There is a complex App, I try to simplify the scenario. There is a host .exe (.NET), which contains lots of controls (ActiveX, .NET, WPF).
One control is basically a grid with items (call it "list"), and when new selection happens, it sends a message to another WPF control (call it "DataView"). "DataView" will display details of the current selection of "list". When DataView receives that message, it will re-create it's ViewModel, and assign to its DataContext, so re-create its View.
Its View is very complex (XAML declared), full of controls, templates, and also contains several Images (type: NonDPIImage, derived from Image, with a few basic non-important change, just consider it as Image), and it's Source is a Converter, which creates the BitmapImages.
<Image.Source>
<MultiBinding Converter="{StaticResource ImageConverter}">
...
It works fine, but I noticed that after selection changes the "DataView" update is getting slower and slower.
I debugged, and found that after several selection changes, all previous Views are still in the memory, and all are rendering its content, so the ImageConverter is called for all previous Views, thus it's getting slower and slower.
I tried to profile, this is what I see after 10+ selection.
You see the previous Views are still in the memory (lower prio problem), with the Images, and those are still being rendered (high prio problem), making the App slower and slower.
I am not really familiar with WPF, I read after leaks (mostly not DependencyProperty is used or similar), but this control is so difficult that first I wand to quickly workaround, so prevent rendering the leaked Views, and later on investigate the memory issue. (of course both would be the best...)
I tried that before DataContext assigned to new value, set the current View Image.Source to null, so at least the leaked Image will not render itself, but that caused the new View(!) also to lose its Image.Source, looks like WPF is caching or sharing like some static data?
As my first prio is to stop the "invisible render", after this I tried to set some of the model properties to null before creating the new one (so it would still leak, but at least no render anymore), so when Converter will receive properties to create the image, will see it's null, and skip the render.
But it behaves very strange!
For the leaked instances the breakpoint is not hit in the properties_get code, like as WPF cached the values or so?
This prevented me this path to continue.
Any help / idea would be appreciated guys.
Can you post your ImageConverter code?
the thing is creating an image from code and serving it as source for Image object,
can create strong link between them and memory leaks in scenarios like yours.
Try looking here:
https://stackoverflow.com/a/21878235/7722174
I think I found the issue: there was a message hook added to the View HwndSource (AddHook()) , but was not removed. This kept the whole View (see the red rectangled class) alive.
Now if I call MyHwndSource.RemoveHook(WndProc) in the UserControl_Unloaded, the View will be also GCd.

WPF Application memory leak issue [duplicate]

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

Solving the memory leak issues

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.

window closed event doesn't release memory and resource. How to solve the memory leak in WPF?

Recently I noticed serious memory leak in my WPF project. If simplify the project, it has a login form and a main form. In main form there are 1 user control which is composed of about 30 user controls and 3 buttons, 1 user control which has 3 buttons and a Infragistics datagrid. I use background worker to query DB every 30 sec only for the datagrid.
After I logout of the main form using main form.closed and re-launch the login window, I noticed that every time there is 6-7MB increase measured by ANTS memory profiler 7. Even though I have unregistered event handlers, set variables to null and called GC.Collect(), memeory leak is still the same. My questions are:
1. Why close wpf window doesn't release the memory and resource? I can see many strings(most of them are from GUI) are still in memory after close window by ANTs profiler.
2. Do I need to unregister the events defined by resource event setter? Do I need to unregister the events declared in XAML?
3. From WPF memory leak, people said we should not use GC.Collect(), but I do see a little improvement. Shall we use it or not?
I have had a simillar problem while using WindowsFormsHost for PictureBox control.
The WPF window using WF PictureBox control could not be fully released and that's why i had a regular ~10mb increase everytime i re-opened the subwindow.
The problem was solved since i started nulling the WFH object on WPF window closing.
Just make sure You clear all the WF controls if You use such.
Break into the debugger and then type this into the Immediate window:
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll
The path to sos.dll varies. The way to find out the correct path is to look for mscorwks.dll in the Modules pane. Wherever that is loaded from is the correct path for sos.dll.
Then type this:
System.GC.Collect()
That will ensure anything not reachable is collected. Then type this:
!DumpHeap -type <some-type-name>
This will show you a table of all existing instances, with addresses. You can find out what is keeping an instance alive like this:
!gcroot <some-address>
originally answered by Daniel
It depends. User controls in WPF do not inherently dispose, so you will have to override the functionality and allow it in your controls with:
http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx
But to your point, you will need to do a GC.Collect() at least once as SlimGG suggests.
In most cases, calling the garbage collector directly is considered bad practice because it is not calling it for your control specifically, but for all objects queued for disposal.

WPF-application memory leak

After certain action (pressing a button that starts a sequence of calculations) in the WPF-application a memory leak occurs (it is visible in the task manager in vm size section) approximately on 10 mbytes after each pressing of the button.
The sequence of calculations does not contain errors.
The use of memory profiler (.NET Memory Profiler) has shown that leaks in .net are not present, but after each pressing of the button the memory size shown in Name/Resource section (marked HeapMemory) increases approximately by 10 mbytes.
I've read posts about leaks in WPF but those are not my case definately.
What can be wrong? Any suggestions? Maybe, someone had the same problem?
Seeing an increase in the used memory is a misnomer in .NET for detecting a memory leak.
It is easy to make a memory leak in WPF, however. I would suggest using a slightly more visual tool like Redgate Ants Memory Profiler (14 day free trial). Use this method to test for leaks:
Press the button once (to eat up any warmup you might have)
Take a snapshot
Press the button again
Take a snapshot
When you go to the "Class List" and check the filter for "From current snapshot show: only new object". This should give you a better picture of whether you have objects that will never be let go.
The other thing about Ants Memory Profiler is that it has links to videos everywhere that instruct you on how to find a leak. Tracking down leaks is a bit of a black art and it's nice to have help.
No, I don't work for Redgate :)
Perhaps you need to use the WeakEvent Pattern as documented on MSDN to avoid leaks?
Listening for events can lead to memory leaks. The typical technique for listening to an event is to use the language-specific syntax that attaches a handler to an event on a source. For instance, in C#, that syntax is: source.SomeEvent += new SomeEventHandler(MyEventHandler).
This technique creates a strong reference from the event source to the event listener. Ordinarily, attaching an event handler for a listener causes the listener to have an object lifetime that influenced by the object lifetime for the source (unless the event handler is explicitly removed). But in certain circumstances you might want the object lifetime of the listener to be controlled only by other factors, such as whether it currently belongs to the visual tree of the application, and not by the lifetime of the source. Whenever the source object lifetime extends beyond the object lifetime of the listener, the normal event pattern leads to a memory leak: the listener is kept alive longer than intended.
(My emphasis.)
I could fix WPF Application memory leak issue by inserting in "thin" places GC.Collect().
Hope this help!

Resources