最近工作中常常被问到如何降低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. Completely change MACE timestamps?

    Hi, One of my friends Sandy asked me about the possibility of completely change MACE timestamps. As ...

  2. hdu2571

    if(x==1) f(x,y)=max{f(x,y-1),f(x,z)}  {y%z==0&&1<y/z<=y&&1<=z<<y} els ...

  3. jquery控制元素的淡入淡出切换

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 001Linux命令

    1.删除非空目录的命令:rm -rf [目录名],r表示迭代,f表示强制: 删除空目录:rmdir [目录名]: 删除文件:rm [文件名]: 2.用户管里类命令: (1)添加用户:useradd [ ...

  5. SE11

        自省数据及表存储 2014年4月6日 21:37     类似JAVA反射的特性 SAP提供自省数据的机制 这样可以保证程序的灵活性和动态性     1.使用OO中的cl_abap_typed ...

  6. ado.net工厂模式DbProviderFactories

    DbProviderFactory f = DbProviderFactories.GetFactory(System.Configuration.ConfigurationManager.Conne ...

  7. windows phone上下文菜单ContextMenu的使用示例

    新建一个WP项目,命名为contextmenu,然后往界面拖入一个ListBox控件listBox1,接着切换到XAML代码界面设置其属性,代码如下 <ListBox Height=" ...

  8. MongoDB(4):多种方式关闭服务命令

    http://blog.csdn.net/czw698/article/details/8791153 MongoDB 提供几种关闭服务的命令,具体为以下: 一 使用 Crtl+C 关闭  [mong ...

  9. 使用junit进行Spring测试

    这几天在做SpringMVC的项目,现在总结一下在测试的时候碰到的一些问题. 以前做项目,是在较新的MyEclipse(2013)上面进行Maven开发,pom.xml 文件是直接复制的,做测试的时候 ...

  10. 7-ZIP实现数据高度压缩

    From:http://www.cnblogs.com/killerlegend/p/3746395.html Author:KillerLegend Date:2013.5.22 选中文件,鼠标右键 ...