Silverlight内存泄露(八)样式

本文通过一个具体的示例探讨了在Silverlight应用中,如何由于ProgressBar样式的不当配置而导致内存泄露的问题。文中提供了详细的样式代码,并展示了如何使用ANTS及ProcessExplorer等工具定位内存泄露的原因。

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

演示Sytle引起的内存泄露

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

例子下载:

例子中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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值