This is a mirror of official site: http://jasper-net.blogspot.com/

Finding Memory Leaks in WPF-based applications

| Wednesday, February 8, 2012
clip_image004_thumb.jpg

There are numbers of blogs that folks wrote about memory leaks in Microsoft .Net Framework managed code and unmanaged code based applications.

In this blog I wanted to:

    Show coding practices that can cause memory leaks which are more unique to WPF-base apps
    Share information about memory leaks in the .NET Framework;
    Show how to avoid these leaks
    Discuss the tools and techniques available to detect the leaks

I plan to update this blog with more code samples as we continue to investigate customers’ applications and find additional platform leaks or coding practices that cause memory leaks in WPF-based applications.


The Sample

To illustrate the issues I attached a sample application. The application can launch different child windows; each can cause a separate memory leak. In each of the cases, closing the child window does not actually release the memory held by Window object as you would expect.


1. Use of Event Handler
    Cause:

    This leak is triggered because the child window (Window2) has a reference (it registered to an event) to Window1 TextBox1 which remains alive causing the Window2 object and its element tree to remain alive.

    In general, if you do this:

            Foo.SomeEvent += new EventHandler(Bar.SomeMethod) 

    Then when you done using Bar, but you are still using Foo then Bar will still remain alive as well. Not what you might have expected.

    Code:

    Window1.w1.TextBox1.TextChanged += new TextChangedEventHandler(this.TextBox1_TextChanged);

    The Window2 object will remains “alive” as long as TextBox1 in Windows1 remain alive.

    The Fix/Workaround:

    There are couple of approaches, the easiest one is simply to un-register the Windows2 object from its various event sources when the windows is about to close.

    e.g.:

    Window1.w1.TextBox1.TextChanged -= new TextChangedEventHandler(TextBox1_TextChanged);

    The second approach is to create some sort of indirections (e.g. “Weak references”). See this Greg Schechter's blog for an example.

2. Use of Data Binding
    Cause:

    This leak documented in this kb article. It is triggered because:

    The TextBlock control has a binding to an object (myGrid) that has a reference back to the TextBlock (it is one of myGrid children’s).

    Note that this type of a DataBinding leak is unique to a specific scenario (and not to all DataBinding scenarios) as documented in the kb article.  The property in the Path is a not a DependencyProperty and not on a class which implements INotifyPropertyChanged and in addition a chain of strong reverences must exist.

    Code:

    myDataBinding = new Binding("Children.Count");
    myDataBinding.Source = myGrid;
    myDataBinding.Mode = BindingMode.OneWay;
    MyTextBlock.SetBinding(TextBlock.TextProperty, myDataBinding);

    Same leaky code can be also written in XAML:

       <TextBlock Name="MyTextBlock" Text="{Binding ElementName=myGrid, Path=Children.Count}" />

    Fix/Workaround:

    There are few of approaches, the easiest one is simply to clear the binding when the windows is about to close.

    e.g.:

          BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);

    Other approach is to set the mode of the data binding to OneTime. See the kb article for other ideas.

Read more: WPF Performance and .NET Framework Client Profile
QR: finding-memory-leaks-in-wpf-based-applications.aspx

Posted via email from Jasper-net