views:

360

answers:

1

It seems that using a DynamicResource to refer to an application level resource can cause memory leaks to occur.

Please see this WPF forum post for more info, how to reproduce it, and some workarounds.

My question is: has anyone else run into it? If so, how have you worked around it?

By the way, there seem to be many situations where this leak does not occur, and maybe the best question is: what exactly are the situations where this leak occurs and does not occur?

For convenience here is the code that reproduces it:

App.xaml

<Application
    x:Class="WeakReferences.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"
>
    <Application.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="SkyBlue"/>
    </Application.Resources>
</Application>

Window1.xaml

<Window
    x:Class="WeakReferences.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1"
    Height="300"
    Width="300"
>
    <Grid>
        <Button
            Name="ReleaseButton"
            Content="Release Reference"
            Click="Button_Click"
        />
    </Grid>
</Window>

Window1.xaml.cs

public partial class Window1 : Window
{
    object p;

    public Window1()
    {
        InitializeComponent();

        p = new Page1();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {            
        p = null;

        GC.Collect();
    }
}

Page1.xaml

<Page
    x:Class="WeakReferences.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Page1"
    Background="{DynamicResource MyBrush}"
>
    <Grid>
    </Grid>
</Page>

Page1.xaml.cs

public partial class Page1 : Page
{
    public Page1()
    {
        InitializeComponent();
    }

    ~Page1()
    {
        Trace.TraceInformation("Page1 Finalized.");
    }
}
+1  A: 

Microsoft has confirmed that this is a bug and that it is fixed in .NET 4.0.

As far as I can tell, this bug only reproduces if the object that is using DynamicResource to refer to an application level resource ... is never made part of the visual tree. Would love to see some counter-evidence to that ... or further clarification on when this leak does occur.

Update: This bug has also been fixed in .NET 3.5. See this hot fix for more info.

cplotts