30行WPF应用程序内存泄漏
我有一个简单的 WPF 应用程序,由一个带有橙色矩形的窗口和一个连续动画组成,该动画会更改应用于矩形的模糊半径。该应用程序当前正在两台计算机上进行浸泡测试,以诊断较大程序中与 WPF 相关的内存泄漏。
在第一台计算机上,内存使用量始终保持平均值,并以与动画持续时间相同的频率轻微振荡。测试程序已可靠运行一周多,没有出现内存泄漏。这台计算机运行的是 Windows 7 32 位。
在第二台计算机上,内存使用量显示出相同的循环行为,但是,每 90 秒内存使用量就会增加约 100kb。只要应用程序正在运行,这种额外的增加就不会被回收。我之前运行过这个程序,直到整个系统内存被这个应用程序耗尽!消耗 4GB 内存的矩形上的动画发光!这台计算机运行的是 Windows 7 嵌入式 32 位。
这两个平台之间存在显着的硬件差异,但是两个系统都运行适用于各自硬件的最新驱动程序。
相同的已编译 exe 在两台未附加调试器的计算机上运行。该应用程序的 XAML 代码如下:
<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>
该代码是针对 .net Framework 4.0 构建的。此 XAML 背后没有 C# 代码。
有谁有任何可能的解释为什么这么简单的程序会泄漏内存?
I have a simple WPF application consisting 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
启用软件渲染修复了该泄漏。在每个 Window_Loaded 事件中,我现在使用以下代码启用软件渲染:
Enabling software rendering has fixed the leak. In each Window_Loaded event I'm now enabling software rendering using the following code:
这是一个
事件处理程序泄漏
。您的 StoryBoard 处理程序之一订阅
FrameworkElement.Loaded
并将保留到最后。我尝试像这样删除
BeginStoryBoard
:但它不起作用。所以到现在为止我还不知道如何解决它。
以下是来自
dotMemory
的处理程序的跟踪。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: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
.