30 line WPF Application Leaking Memory
I have a simple WPF application consis开发者_开发技巧ting of a Window with an orange rectangle and a continuous animation which changes a blur radius which is applied to the rectangle. This application is currently soak testing on two computers in order to diagnose a memory leak related to WPF in a larger program.
On the first computer, the memory usage is consistently maintaining an average which oscillates slightly at the same frequency as the animation duration. The test program has been running reliably for over a week without leaking memory. This computer is running windows 7 32-bit.
On the second computer, the memory usage is showing the same cyclic behaviour, however ~ every 90 seconds the memory usage is increasing by around 100kb. This extra increase is never reclaimed for as long as the application is running. I have previously run this program until the entire system memory is consumed by this one application! An animated glow on a rectangle consuming 4gb of ram! This computer is running windows 7 embedded 32-bit.
There is a significant hardware difference between the two platforms, however both systems are running the latest drivers available for their respective hardware.
The same compiled exe is on both computers running without debuggers attached. The XAML code for the application is included below:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfAnimation.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="Flash" AutoReverse="True" RepeatBehavior="Forever" FillBehavior="Stop">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(BlurEffect.Radius)" Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="15">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Flash}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Rectangle x:Name="rectangle" Fill="#FFFFA400" Margin="113,93,125,101" Stroke="Red" RadiusX="10" RadiusY="10" StrokeThickness="5">
<Rectangle.Effect>
<BlurEffect KernelType="Box" Radius="0"/>
</Rectangle.Effect>
</Rectangle>
</Grid>
</Window>
This code was built against .net Framework 4.0. There is no C# code behind this XAML.
Does anyone have any possible explanation as to why a program this simple is leaking memory?
Enabling software rendering has fixed the leak. In each Window_Loaded event I'm now enabling software rendering using the following code:
public static void EnableSoftwareRendering(Visual visual)
{
try
{
HwndSource source = PresentationSource.FromVisual(visual) as HwndSource;
HwndTarget target = source.CompositionTarget;
target.RenderMode = RenderMode.SoftwareOnly;
}
catch
{ }
}
It is an Event handlers leak
.
One of your StoryBoard handler subscribes to FrameworkElement.Loaded
and will be retained to the end.
I tried to remove BeginStoryBoard
like this:
<EventTrigger RoutedEvent="UserControl.Unloaded" SourceName="CellControl">
<RemoveStoryboard BeginStoryboardName="MouseEnterStoryBoard"/>
</EventTrigger>
But it does not work. So I have no idea how to fix it till now.
The following is the trace of the handler from dotMemory
.
System.Windows.Media.Animation.BeginStoryboard._inheritanceContext ->
System.Windows.EventTrigger._routedEventHandler ->
System.Windows.RoutedEventHandler._target ->
System.Windows.EventTrigger+EventTriggerSourceListener
精彩评论