zoukankan      html  css  js  c++  java
  • silverlight内存问题总结(三)—silverlight控件内存泄露

      DataGrid 我想任何一个写过.NET的人都知道,这是微软报表展示使用面非常广的控件,其实很多书,包过网上很多文章,帮助文档对这个控件的介绍都是介绍怎么使用控件,应该几乎没什么人会知道这个控件会有内存泄露吧。刚接手B/S工作站系统由于对整个系统不熟悉,而且对Silverlight比较技术陌生,所以单独把系统中一块报表数据刷新抽出来观察。这个小案例再后面的研究起了很大作用,当然前期也给我带来很多的干扰,让我前一个月的研究和实验没有任何进展。下面看个简单的例子:

    问题描述:

    while(true)

    {

        Thread.sleep(3*1000);

                  this.Dispatcher.BeginInvoke(         //访问界面UI
                      delegate
                      {

               /*

           do some  changed  on the collction of QueueItemSource

                 */

                           datagrid.ItemsSource = null;

                           datagrid.ItemsSource = QueueItemSource;//存在内存泄露
                      });

    }

         上述这段代码是在一个线程的里面一直跑,每跑一次停留3秒,datagrid.ItemsSource = null; 只要对垃圾回收器稍微有所了解人都知道这行代码,如果没有其它地方引用的话,原先绑定在datagrid.ItemsSource 就会被回收,QueueItemSource有做修改,但是修改完后都要克隆一下,与绑定到datagrid.ItemsSource 不存在任何内存对象数据共享。datagrid.ItemsSource = QueueItemSource 这句话在Asp.net和winform应该都没有问题,但是在Silverlight中  确会发生泄漏,原因很简单:Silverlight数据和控件的绑定是双通道的,修改数据会直接反应到前台界面,从前台界面修改数据会反映到后台数据集中,为了实现这一个功能,微软在数据绑定时候会向控件注册一个事件,这个事件用来当一方数据发生变通知另一方数据也要做相应的变化,不断的循环订阅事件,事件是要占内存,由此而产生泄漏,一个晚上大概泄漏20M左右。我想任何一个人,即使他对.NET框架底层的东西,对垃圾回器,对CLR运行时再熟悉也也很难想象到会有这样一个问题,很显然这是微软的BUG,每次绑定数据前应该把原有的事件卸载掉,不过微软技术专家是不会承认这样的BUG,他们会一如既往地认为这是用户使用不当造成的。

    解决方案:

          由于代码在公司所以没有办法把代码贴出来,解决方法其实很简单,那就是我只绑定一次,后面的循环我只是修改数据,不做任何的重新绑定,简单地说只是在数据与数据之间做一个类似深拷贝的东西,当然这种大规模的深拷贝导致CPU涨得比较厉害,后面也进行了一轮CPU的优化但是CPU降得的效果不是特别明显,当然速度提高了很多。

  • 相关阅读:
    set 用法、小结
    AC 自动机优化
    HDU 2222 Keywords Search 【ac自动机】
    组合数学 隔板法
    BZOJ1303_中位数图_KEY
    初识Trie_对Trie的一些认识
    网络流Edmonds-Karp算法入门
    Codevs1332_上白泽慧音_KEY
    Fliptil_KEY
    2017Noip普及组游记
  • 原文地址:https://www.cnblogs.com/zhengjianfeng/p/1863468.html
Copyright © 2011-2022 走看看