最近工作中常常被问到如何降低WP内存使用,便再一次开始研究内存问题,首先发现了LonglistSelector使用的一个常见问题:

概述

若将Longlistselector 控件的ItemsSource设置为ViewModel中的一个ObservableCollection集合,那么应该值得注意内存问题。

问题的产生

下面的demo中,模拟了如下场景ItemSource Binding到了Page以外的静态ObservableCollection上。那么如果我们的程序结构如果是

MainPage->LoginPage 的话,来回在MainPage和LoginPage间切换就会导致内存中有多个LoginPage不能被释

namespace Feinno.Beside.View.Pages
{
public class BindingSource
{
public static ObservableCollection<object> Collection =
new ObservableCollection<object>();
}
public partial class LoginPage : PhoneApplicationPage
{
public LoginPage()
{
InitializeComponent ();
       //List 为xaml中定义的Longlistselector
list .ItemsSource = BindingSource.Collection;
Debug .WriteLine("Initialze page!! hashcode = " + GetHashCode());
}
~LoginPage()
{
Debug .WriteLine("Uninitialze page!! hashcode = " + GetHashCode());
}
}
}

正常状态(无内存问题)的打印如下:             而上面代码的打印如下:

page可以及时销毁。

                             

可以看出,在来回切换页面的时候,之前的页面并没有得到释放,而是一只在内存中。

产生原因

笔者尝试使用Listbox来执行同样的代码,并不会出现上述问题,所以分析感觉是Windows Phone 8 新增的Longlistselector有问题,

具体原因是因为ObservableCollection 对外会暴露CollectionChanged接口将LonglistSelector的ItemSource赋值为ObservableCollection的时候,LonglistSelector通过此接口来监听列表中集合的改变,由于使用的是强事件,那么ObservableCollection中将会持有对LonglistSelector的引用,如此便导致离开页面之后,GC回收资源的时候,认为LoginPage仍在使用中,从而导致我们不希望看到的结果。

解决办法   

当存在上述类似场景的Itemsource设定时,在页面离开时将Itemsource设为null

深入分析

如此说来若Page中的控件Binding到代码中的Binding Source会如何呢?

通过写Demo分析以及查阅相关资料,笔者得出一下结论:

1、LonglistSelector.ItemSource(ListBox无此问题)如果Binding到ObservableCollection,结果和上文中一致,Page无法释放。

2、其他属性的Binding 不会导致上述问题。

对结论的理论支持:

查阅资料笔者了解到,Binding机制内部实现了叫做WeakEventManager的机制,因此Binding监听属性变更,同Event机制存在差异。若控件A Binding到VM中的属性B上,当GC准备回收A 的时候,不会认为A 存在引用。

参考:

Weak Event Patterns:http://msdn.microsoft.com/en-us/library/aa970850.aspx

Do WPF controls use weak events in their bindings?

关于WP的交流欢迎加入QQ群:182659848

如有任何疑问,欢迎留言给我。

Windows Phone 8内存控制研究 之 LonglistSelector使用陷阱的更多相关文章

  1. RabbitMQ 内存控制 硬盘控制

    RabbitMQ服务器在启动时以及abbitmqctl set_vm_memory_high_watermark fraction 执行时,会检查计算机的RAM总大小. 默认情况下下, 当 Rabbi ...

  2. 《深入浅出Node.js》第5章 内存控制(未完)

    @by Ruth92(转载请注明出处) 第5章 内存控制 基于无阻塞.事件驱动建立的 Node 服务,具有内存消耗低的优点,非常适合处理海量的网络请求. 内存控制正是在海量请求和长时间运行的前提下进行 ...

  3. 关于32位windows与4GB内存的那些事儿

    参考:1 Physical Address Extensionzh.wikipedia.org/wiki/PAEen.wikipedia.org/wiki/Physical_Address_Exten ...

  4. 《疯狂Java:突破程序员基本功的16课》读书笔记-第二章 对象与内存控制

    Java内存管理分为两个方面:内存分配和内存回收.这里的内存分配特指创建Java对象时JVM为该对象在堆内存中所分配的内存空间.内存回收指的是当该Java对象失去引用,变成垃圾时,JVM的垃圾回收机制 ...

  5. [Windows Phone] 导览控制项(Navigation controls)

    原文:[Windows Phone] 导览控制项(Navigation controls) [前言] 如果应用程式只有单一页面,在画面呈现上可能会让使用者容易没有新鲜感,这个范例是使用导览控制项(Na ...

  6. Windows任务管理器中内存使用、虚拟内存区别及与页面文件的关系

    原文地址:Windows任务管理器中内存使用.虚拟内存区别及与页面文件的关系 虚拟内存(VirtualMemory)是Windows管理所有可用内存的方式.对于32位Windows系统,每个进程所用到 ...

  7. windows 下共享内存使用方法示例

    windows下共享内存使用方法较 linux 而言微微复杂 示例实现的功能 有一个视频文件,一块内存区域 : 程序 A,将该视频写入该内存区域 : 程序 B,从该内存区域读取该视频 : 代码模块实现 ...

  8. windows内核驱动内存管理之Lookaside使用

    Windows内存管理中使用了类似于容器的东西,叫做Lookaside对象,每次程序员申请内存都会从Lookaside里面申请,只有不足的时候,Lookaside才会向内存又一次申请内存空间,这样减少 ...

  9. Windows系统中内存泄露与检测工具及方法

    1.检测需要使用的工具:windbg工具.检测前,需要先安装windbg工具.安装了该工具后,会在安装目录下有一个umdh工具.假设windbg安装在以下目录下:D:\Program Files\De ...

随机推荐

  1. UI Button

    iOS开发UI篇—Button基础 一.简单说明 一般情况下,点击某个控件后,会做出相应反应的都是按钮 按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置 二.按钮的三种状 ...

  2. 破解金盘gdlisxp系统

    1.现在要破解的金盘gdlisxp系统版本 2.首先在你电脑上要有脱壳工具AspackDie,和OllyDBG动态调试工具,电脑上装好金盘软件. 3.用AspackDie进行对金盘应用程序脱壳处理,生 ...

  3. Java基本开发环境搭建(适合第一次使用)

    Java基本开发环境搭建(适合第一次使用) 编写人:cc 阿爸 2013-10-17 一.开发工具获取 1.开发工具包JDK l  下载地址: 到ORACLE公司官方网站(http://www.ora ...

  4. 用过的一些js函数[备份用的]

    1.类似php的htmlspecialchars函数,如需要可以自行增加其它代替 function _htmlspecialchars(str) { str = str.replace(/&/ ...

  5. Android Socket通信

    1.TCP: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...

  6. jquery 点击页面其他地方实现隐藏菜单功能

    1.给页面文档添加一个点击事件函数,在函数内实现隐藏菜单功能. $('html').click(function(){//Hide the menus if visible});//用$(docume ...

  7. SSD1306驱动的OLED实验

    [转]http://bbs.21ic.com/icview-434543-1-1.html 前面几章的实例,均没涉及到液晶显示,这一章,我们将向大家介绍OLED的使用.在本章中,我们将使用战舰STM3 ...

  8. EmguCV学习——简单使用

    关于EmguCV我就不多说了,是对应于OpenCV的一套net库. 公司是视觉方面的业务,我又不会c++(好想会啊,正在学习中).由于各种需求,自己觉得对c++不是特别感冒,所以选用了net下的ope ...

  9. equals方法,hashcode()方法

    Object类的equals 方法 用来检测两个对象是否相等,即两个对象的内容是否相等,区分大小写.   (一)说到equals方法,不得不提一下==号. ==用于比较引用和比较原生数据类型时具有不同 ...

  10. 误删system04.dbf 报:ORA-01157 ORA-01110

    DB:Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production OS:Oracle Linux 5.7 ...