I've got a managed memory leak in my WP7 app when using ControlTemplate.
This can be reproduced in a vanilla WP7.1 project using the attached code.
See the "Uncomment the following to see the problem" below...
Simply navigate forward and backwards in the test application. I would expect the Page1.xaml to be garbage collected, but it isn't when a ControlTemplate is defined...
Output without the ControlTemplate:
In In In Out In Out In Out In Out
Output with the ControlTemplate:
In In In In In In In
In either case, when the applciation exits, you see the remaining debug "Out" statements printing.
Does anyone have any idea why the definition of 'ControlTemplate' would cause the page to remain in memory?
Many thanks for any help,
Jon
MainPage.xaml
<phone:PhoneApplicationPage
x:Class="PhoneApp1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Button Click="Button_Click">
<TextBlock Text="Click me..." />
</Button>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
MainPage.xaml.cs
using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
namespace PhoneApp1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
GC.Collect();
}
}
}
Page1.xaml
<phone:PhoneApplicationPage
x:Class="PhoneApp1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
shell:SystemTray.IsVisible="True" mc:Ignorable="d" d开发者_Go百科:DesignHeight="768" d:DesignWidth="480">
<phone:PhoneApplicationPage.Resources>
<Style x:Key="CheckBoxButtonStyle" TargetType="CheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<!-- Uncomment the following to see the problem -->
<!--<Grid Background="Transparent"></Grid>-->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent"></Grid>
</phone:PhoneApplicationPage>
Page1.xaml.cs
using System.Diagnostics;
using Microsoft.Phone.Controls;
namespace PhoneApp1
{
public partial class Page1 : PhoneApplicationPage
{
public Page1()
{
InitializeComponent();
Debug.WriteLine("In");
}
~Page1()
{
Debug.WriteLine("Out");
}
}
}
It does seem to be a pretty common memory leak, especially since standard WP7 applications (non-XNA apps) are working with the same fundamental Silverlight classes. There is an entire thread on the Silverlight Forums dedicated to this issue.
Initially, the solution was to use inline templates, but the leak still persists in my test cases. If you move the template to App.xaml
, the leak is not there anymore.
精彩评论