Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Isolate Silverlight Memory Leaks

I have a memory leak in a silverlight app, I used this information to get started,

http://blogs.msdn.com/b/slperf/archive/2010/08/19/analyzing-silverlight-memory-usage-part-1-obtaining-measurements.aspx

Which was excellent. I have extracted some of my code to break down the issue. So the code looks like this, a child window,

<controls:ChildWindow x:Class="MemoryLeakTesting2.ConfirmDialog"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
       xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls"        
       Width="375"   >
    <Grid Margin="2">
        <telerik:RadButton Content="OK" Click="OnClick" Command="{Binding CancelActionCommand}" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>

The code behind is this,

public partial class ConfirmDialog : ChildWindow
{
    public ConfirmDialog()
    {
        InitializeComponent();
    }

    [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    private void OnClick(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
    }
}

I am calling this code from the button click event in my main silverlight page like this,

private void Button_Click(object sender, RoutedEventArgs e)
{
    ConfirmDialog dialog = new ConfirmDialog();
    dialog.Show();
}

This leaks memory every time I open the popup and close it. I use WinDbg and it actually shows that the ConfirmDialog instance is not freed after each time it is popped up and closed??

like image 969
peter Avatar asked Nov 05 '22 20:11

peter


2 Answers

The Button.Command is notorious for leaking. My guess is that the value CancelActionCommand has a reference to a long lived object. The Button won't unhook from the ICommand.CanExecuteChanged event. You should consider using a Weak Event Pattern to limit your leakable surface area.

Here is a better explanation and example code to fix the problem.

like image 179
Ed Chapel Avatar answered Nov 14 '22 10:11

Ed Chapel


Could it be:

On every click event you are creating ConfirmDialog object, which might hang around after it is no longer being used. Can you create that as a class variable and only have one reference and use that instead when you need to show the ChildWindow

like image 32
VoodooChild Avatar answered Nov 14 '22 11:11

VoodooChild