UWP开发入门(十六)——常见的内存泄漏的原因
本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍。
内存泄漏的概念我这里就不说了,之前《UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏》中提到过,即使有垃圾回收机制,写C#还是有可能发生内存泄漏。
一般来说,以下两种情况会导致内存泄漏:
- 对象用完了但是没有释放资源
- 对象本身是做了清理内存的操作,但是对象内部的子对象没有成功释放资源
下面就UWP开发中具体的实例来说明需要避免的写法
- 从static/global的对象上注册了事件
FakeService.Instance.ShowMeTheMoneyEvent += Instance_ShowMeTheMoneyEvent;
比如我们有一个底层的FakeService,提供整个APP生命周期的数据和网络的访问。假设某个页面+=了这个FackService的Event,在离开页面时没有-=掉。那么该页面就无法被垃圾回收。
合理的做法是在OnNavigatedFrom方法里,把事件反注册掉。
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
FakeService.Instance.ShowMeTheMoneyEvent -= Instance_ShowMeTheMoneyEvent;
}
- DispatcherTimer事件未关闭
这种情况就属于对象内部的属性未能被释放,假设页面内部存在Timer对象:
public sealed partial class TimerPage : Page
{
private DispatcherTimer Timer { get; set; } = new DispatcherTimer(); public ArrayList arrayList { get; set; } public TimerPage()
{
this.InitializeComponent();
arrayList = new ArrayList();
Timer.Tick += Timer_Tick;
Timer.Interval = TimeSpan.FromSeconds();
Timer.Start();
} private void Timer_Tick(object sender, object e)
{
int count = ;
int.TryParse(TextBoxTimer.Text, out count);
count += ;
TextBoxTimer.Text = count.ToString();
} private void Button_Click(object sender, RoutedEventArgs e)
{
this.Frame.GoBack();
} protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Timer.Stop();
}
}
如果在离开页面之前,未调用Timer对象的Stop方法,也未-=Tick事件(这里Stop方法会自动-=Tick事件)。该页面就不能正常的回收。
这里并不是说所有的Event都需要在OnNavigatedFrom方法中-=,例如Control本身的Loaded、IsEnabledChanged等事件等并不会造成内存泄漏,反注册这些事件是为了避免事件的重复触发。而DispatcherTimer比较特殊,我理解它会把自己加到一个专门维护计时器的队列中,然后不停的触发Tick事件,如果没有Stop或-=,就等于Timer一直引用了外部的对象,从而导致页面本身也无法回收。
- Data Binding Memory Leak
这一条在很多的文档上有所提及,很遗憾我没法通过Diagnostic Tools监测出来具体的泄漏,我猜测可能是很小规模的内存泄漏。但是避免的方式非常容易,只要平时写XAML注意一下就可以了。
会出现问题的写法是以下两种:
- 未实现INotifyPropertyChanged的对象,而你又想监测Property变化
- 未实现INotifyCollectionChanged 接口的集合,而你又想监测Collection变化
其实很好处理。如果想监测变化,就老老实实继承对应的接口。如果使用了普通的Property和集合,并且不想监测变化,一定记得Mode = OneTime。
当然如果属性本身是dependency property,就不存在内存泄漏的情况了。
<!--内存泄漏,因为Children集合没有实现INotifyPropertyChanged来通知Count属性变化-->
<TextBlock Text="{Binding ElementName=layoutRoot, Path=Children.Count}" />
<!--不会内存泄漏,因为ActualWidth是依赖属性-->
<TextBlock Text="{Binding ElementName=layoutRoot, Path=ActualWidth}" />
<!--不会内存泄漏,因为Mode = OneTime-->
<TextBlock Text="{Binding ElementName=layoutRoot, Path=Children.Count, Mode = OneTime}" />
- 非托管资源的释放
这个都非常熟悉,不多说了。主要是通过using语句,或者在try { … } finally { … }中调用Dispose或者Close方法来释放非托管资源。
UWP开发入门(十六)——常见的内存泄漏的原因的更多相关文章
- Android内存管理(13)常见产生内存泄漏的原因
1.集合类泄漏 集合类如果仅仅有添加元素的方法,而没有相应的删除机制,导致内存被占用.如果这个集合类是全局性的变量 (比如类中的静态属性,全局性的 map 等即有静态引用或 final 一直指向它), ...
- UWP开发入门(六)——对多设备不同分辨率显示效果的讨论
本篇不涉及具体代码,而是把实际开发UWP APP的过程中,遇到的不同设备,不同分辨率显示效果差异的问题进行讨论.希望能够抛砖引玉,和各位擦出一些火花. 蜀黍我目前是在做一套牛逼的UWP APP啦,目标 ...
- UWP开发入门(十)——通过继承来扩展ListView
本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...
- UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏
因为.NET的垃圾回收机制相当完善,通常情况下我们是不需要关心内存泄漏的.问题人一但傻起来,连自己都会害怕,几个页面跳啊跳的,内存蹭蹭的往上涨,拉都拉不住.这种时候我们就需要冷静下来,泡一杯热巧克力. ...
- S3C2416裸机开发系列十六_sd卡驱动实现
S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子 1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...
- UWP开发入门系列笔记之(一):UWP初览
标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...
- Android开发 |常见的内存泄漏问题及解决办法
在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...
- 5个Android开发中比较常见的内存泄漏问题及解决办法
android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了. 内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...
- UWP开发入门(四)——自定义CommandBar
各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...
随机推荐
- UVA 1101 To Add or to Multiply
首先我们观察加操作和乘操作会对区间产生那些影响.加操作只会平移区间,而乘操作既能移动区间还能放大区间.因此我们不难想到,如果m>1的话乘操作是log级别的,一方面是因为区间的大小不能超过s-r, ...
- Logdump使用指引
Logdump使用指引 Logdump使用指引在GGSCI中使用如下命令查看当前处理的队列文件和RBA号,例如:GGSCI (br-jl-accs-db1) 3> info REPYXAREPL ...
- 如何准备IREB考试
最近准备International Requirement Engeering Board 考试,但凡上点年纪对记忆就不行了,时间也不够,就想着怎么偷懒. 因此,就把测试题做了一遍,然后分析各个章节的 ...
- android 电量分析工具
.参考文章:https://developer.android.com/studio/profile/battery-historian.html 这篇文章讲的是如果dump 电量日子文件batter ...
- State状态设计模式
1.状态模式:改变对象的行为 一个用来改变类的(状态的)对象. 2:问题:当你自己实现 State 模式的时候就会碰到很多细节的问题,你必须根据自己的需要选择合适的实现方法, 比如用到的状态(Stat ...
- Java基础集锦——利用Collections.sort方法对list排序
要想对List进行排序,可以让实体对象实现Comparable接口,重写compareTo方法即可实现按某一属性排序,但是这种写法很单一,只能按照固定的一个属性排序,没变法变化.通过下面这种方法,可以 ...
- 用git上传本地项目到github上
首先确认自己已经安装了git,打开git bash,输入ssh-keygen -t rsa -C "自己的邮箱地址@XXX.com" ,生成自己的公钥与私钥 一路默认回车,会生 ...
- Embeding Python & Extending Python with FFPython
Introduction ffpython is a C++ lib, which is to simplify tasks that embed Python and extend Python. ...
- jQuery 焦点图 旋转木马
jQuery BxSlider 滑动滚动效果 jQuery Easing 动画效果扩展
- 在线读取office 文件(Word excel 等)
https://view.officeapps.live.com/op/view.aspx?src=http://www.xxx.com/uploadfile/app/11.xls src 后面的网址 ...