dinghao

记录成长点滴

 

Silverlight内存泄露(八)样式

同一个程序,换一个主题、换一个样式,可能造成内存泄露。

演示Sytle引起的内存泄露

这一系列写到八了,将要结束,还没有一个直观例子说不过去,样式发生内存问题最难找也最隐蔽,做了小例子说明内存泄露问题。

例子下载:

MemoryLeak.rar 

例子中ProgressBar样式引起内存泄露,为直观每次导航分配50M内存。

a) 继续使用ANTS检测内存问题,但ANTS属于收费软件

b) 也可使用免费的进程浏览器,启动 Process Explorer.,在sllauncher.exe进程右击,选择属性,在Home、About间导航。

clip_image002

每次导航内存增加50M

clip_image004

注释掉ProgressBar样式后,内存不增加。

查找内存泄露

给程序更换样式后发现,View不能释放,没导航内存都增加一个View实例。查看其中一个内存关系图,如下:

clip_image006

可看到某个动画的引用不能释放。造成View不能释放

ProgressBar样式造成内存泄露

产生内存泄露的样式:

<!--progressbar 内存泄露-->
<Style TargetType="ProgressBar">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Maximum" Value="100" />
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Grid x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="0"
Storyboard.TargetName
="ProgressBarRootGrid"
Storyboard.TargetProperty
="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0"
Storyboard.TargetName
="ProgressBarIndeterminateRootGrid"
Storyboard.TargetProperty
="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="tr" Storyboard.TargetProperty="X"
Duration
="0:0:2" To="0.8" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="gs2" Storyboard.TargetProperty="Offset"
BeginTime
="0:0:0" Duration="0:0:4"
RepeatBehavior
="Forever">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="0.1"/>
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="0"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="gs3" Storyboard.TargetProperty="Offset"
BeginTime
="0:0:0" Duration="0:0:4"
RepeatBehavior
="Forever">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="0.2"/>
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="0.1"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ProgressBarTrack" CornerRadius="4"
Background
="{TemplateBinding Background}"
BorderThickness
="{TemplateBinding BorderThickness}"
BorderBrush
="{TemplateBinding BorderBrush}" />
<Grid x:Name="ProgressBarRootGrid" >
<Rectangle HorizontalAlignment="Left" x:Name="ProgressBarIndicator"
Margin
="3" RadiusX="3" RadiusY="3"
Fill
="{TemplateBinding Foreground}"/>
</Grid>
<Grid x:Name="ProgressBarIndeterminateRootGrid" Visibility="Collapsed">
<Rectangle Margin="3" RadiusX="3" RadiusY="3" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0 0.5" EndPoint="1 0.5">
<LinearGradientBrush.RelativeTransform>
<TranslateTransform x:Name="tr" X="0"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop x:Name="gs0" Offset="0" Color="Transparent"/>
<GradientStop x:Name="gs1" Offset="0" Color="Transparent"/>
<GradientStop x:Name="gs2" Offset="0" Color="#CCCCFF"/>
<GradientStop x:Name="gs3" Offset="0.2" Color="#CCCCFF"/>
<GradientStop x:Name="gs4" Offset="0.2" Color="Transparent"/>
<GradientStop x:Name="gs5" Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

结论

a) 估计是Silverlight4bug,silverlight5没测试。

b) 慎用第三方样式

安装Silverlight5的问题

Silverlight5安装不上,有知道怎么解决下面问题的请回复。

clip_image008

posted on 2011-04-18 13:28  思无邪  阅读(1968)  评论(6编辑  收藏  举报

导航