本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍。

  内存泄漏的概念我这里就不说了,之前《UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏》中提到过,即使有垃圾回收机制,写C#还是有可能发生内存泄漏。

  一般来说,以下两种情况会导致内存泄漏:

  1. 对象用完了但是没有释放资源
  1. 对象本身是做了清理内存的操作,但是对象内部的子对象没有成功释放资源

  下面就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注意一下就可以了。

  会出现问题的写法是以下两种:

  1. 未实现INotifyPropertyChanged的对象,而你又想监测Property变化
  2. 未实现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开发入门(十六)——常见的内存泄漏的原因的更多相关文章

  1. Android内存管理(13)常见产生内存泄漏的原因

    1.集合类泄漏 集合类如果仅仅有添加元素的方法,而没有相应的删除机制,导致内存被占用.如果这个集合类是全局性的变量 (比如类中的静态属性,全局性的 map 等即有静态引用或 final 一直指向它), ...

  2. UWP开发入门(六)——对多设备不同分辨率显示效果的讨论

    本篇不涉及具体代码,而是把实际开发UWP APP的过程中,遇到的不同设备,不同分辨率显示效果差异的问题进行讨论.希望能够抛砖引玉,和各位擦出一些火花. 蜀黍我目前是在做一套牛逼的UWP APP啦,目标 ...

  3. UWP开发入门(十)——通过继承来扩展ListView

    本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...

  4. UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏

    因为.NET的垃圾回收机制相当完善,通常情况下我们是不需要关心内存泄漏的.问题人一但傻起来,连自己都会害怕,几个页面跳啊跳的,内存蹭蹭的往上涨,拉都拉不住.这种时候我们就需要冷静下来,泡一杯热巧克力. ...

  5. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...

  6. UWP开发入门系列笔记之(一):UWP初览

    标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...

  7. Android开发 |常见的内存泄漏问题及解决办法

    在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...

  8. 5个Android开发中比较常见的内存泄漏问题及解决办法

    android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了.   内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...

  9. UWP开发入门(四)——自定义CommandBar

    各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...

随机推荐

  1. win7下安装ubuntu13.04

    http://teliute.org/linux/Ubsetup/jichu1/jichu1.html xp下安装 http://flysqrlboy.blog.51cto.com/5027074/8 ...

  2. 连上VPN后,如何访问内网(添加路由表实现网络分流方法)

    route add 192.168.4.0 mask 255.255.255.0 192.168.2.0 metric 1 不止有“邮件系统”会出现这种情况,还有其他情况,这时,你需要在没有连接外网和 ...

  3. mac osx 系统 brew install hadoop 安装指南

    mac osx 系统 brew  install hadoop 安装指南   brew install hadoop 配置 core-site.xml:配置hdfs文件地址(记得chmod 对应文件夹 ...

  4. 给Number类型增加加法、减、乘、除函数,解决float相加结果精度错乱的问题

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  5. Hadoop 2.7.1 源代码目录结构分析

    采用的源代码是2.7.1的,从这个网站下可以找到2.7.1的代码:https://git1-us-west.apache.org/ ,使用gitclone出来,然后git checkout到2.7.1 ...

  6. 我的常用mixin 之 lines

    /** * 最多显示 $lineCount 行 * lines * * example: * @include lines; * @include lines(3); */ @mixin lines( ...

  7. android Camera 结构

    Java层 :Frameworks\base\core\java\android\hardware\Camera.java JNI: Frameworks\base\core\jni\android_ ...

  8. MyEclipse设置编码方式

    1.windows->Preferences……打开"首选项"对话框,左侧导航树,导航到general->Workspace, 右侧Text file encoding ...

  9. android中自定义view---实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色

    android自定义view,实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色. 由于时间比较仓促,因此没有对代码进行过多的优化,功能远远不如androi ...

  10. 阅读《Effective C++》系列

    <Effective C++>条款07:为多态基类声明virtual析构函数 这样做主要是为了防止内存泄漏,见我hexo博客. C++的虚析构函数 <Effective C++> ...