WPF不明内存泄露已解决,白头发也没了

阅读: 1452 评论: 6 做者: 周 金根 发表于 2010-06-02 14:12 原文连接html

     在上一篇中求助了一个内存泄露问题【WPF不明内存泄露缘由,头发都白了几根】,本篇与你们分享一下如何解决此问题的过程。架构

问题发现

  用户使用产品时,使用久了会报出内存溢出错误,因而开始查找内存泄露问题。在【WPF -.Net 4.0解决了DataGrid分组时的内存泄露】中介绍了一个DataGrid内存泄露问题,这里主要说的是关闭模块后对象仍没有释放的问题。wordpress

问题解决

  这个问题在本周以前已经由另外一同事使用ANTS Memory Profiler 5查看定位到是Button致使,可是缘由不明。因为内存泄漏不是小问题,因此我决定这周看看。工具

继续查找缘由

  使用ANTS Memory Profiler 5查看内存泄露问题,找到问题是在Button上,可是搞不清为何会在button上,特别是加上了WPF的DependencyObject的一些东西,若是想要弄明白以为还不简单。周一开始有时间我就对这个问题进行定位,可是到今天仍旧没有头绪:(  因而开始找其余办法。测试

 

  • 使用其它内存泄露工具看看
    网上google了一下内存泄露工具,随便点击一个,下载了Scitech memory profiler试用版本,新建项目后跑了一下程序,关闭模块后拍了一个快照,在Type Details页签输入ProjectList类库,显示下图,其路径和上图路径是同样的:

    可是这个工具好在能够看到调用堆栈(可能ANTS Memory Profiler也有这个功能,只是我不知道),切换几个类查看堆栈,找到了在OpenExpressApp中的类库,高兴阿,以下图:

    从上图能够看出多是在ButtonCommand.SetCommand中代码致使泄漏的。

  • 今天上午发帖【WPF -.Net 4.0解决了DataGrid分组时的内存泄露
    很感谢不少朋友立刻给我回复,其中李永京确定是有经验的高手,经过个人一个图就能猜出问题所在,我想之前他也必定受到这个的困扰。他的回复是这样的:
        
    <

    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    > LZ 是否是用DependencyPropertyDescriptor.FromProperty
    这样获得属性而后用 AddValueChanged加了委托跟踪属性值的变化,最后在unload的时候去掉下。

    这个是猜想,没有具体代码也很难分析。

解决办法

  经过上面的查找,基本定位可能出如今跟踪属性值变化的AddValueChanged中,查看项目代码,发现的确使用了网站

因而google搜索【PropertyDescriptor AddValueChanged leak】,看到了一篇于此相关的blog:PropertyDescriptor AddValueChanged Alternative。看了一下这篇文章,知道是因为事件强引用致使,blog中也提出了一个解决办法,就是创建一个PropertyChangeNotifier类,经过弱引用对象创建属性值更改事件的绑定,具体代码和说明参考这篇bolg便可PropertyDescriptor AddValueChanged Alternative,我就再也不详述了。google

  问题定位了,解决方法也有了,因而开始动刀修改问题:全文搜索一下 DependencyPropertyDescriptor.FromProperty,发现有两处使用了,都是OpenExpressApp中引用的外部代码,一个是封装Command的ButtonCommand,一个限制ListView宽度的ViewLayoutManager,代码修改以下所示:(你们也能够经过WeakEventManager来解决)编码

                //memory leak, use PropertyChangeNotifier
                //DependencyPropertyDescriptor.FromProperty(
                //    Button.IsEnabledProperty,
                //    typeof(Button)).AddValueChanged(button, ButtonIsEnabledChanged);

                PropertyChangeNotifier notifier = new PropertyChangeNotifier(button, "IsEnabled");
                notifier.ValueChanged += new EventHandler(ButtonIsEnabledChanged);
  代码修改再跑测试,发现已经找不到这个对象了,终于解决了这个问题了:) 开始着手寻找其它内存泄漏问题,不过如今有
Scitech memory profiler应该可以更快定位了spa

回顾

  • 事件强引用是.Net下内存泄漏的常出现的因为编码不注意致使的问题

Leak Description3d

Developer Error

Improper Use of Event Handlers

X

Improper Use of Data Binding

X

Improper Use of Command Binding

X

Improper Use of Static Event Handlers

X

  • 设定任务timebox,到时还未解决,能够尝试其它工具方法:例如使用其它工具;寻求有经验的热心人帮忙

 

相关blog

WPF -.Net 4.0解决了DataGrid分组时的内存泄露

WPF不明内存泄露缘由,头发都白了几根

 

 

欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

评论: 6 查看评论 发表评论

沪江网招聘ASP.NET开发工程师


最新新闻:
· 谷歌收购广告公司Invite Media(2010-06-02 22:16)
· AT&T拟推新数据计划 iPad 3G用户再也不享有无限(2010-06-02 21:36)
· 支持ARM架构:新版嵌入式Windows 7 CTP发布(2010-06-02 19:51)
· Apple的平台之路(三)(2010-06-02 19:27)
· Ubuntu 10.04可支持iPhone(2010-06-02 18:14)

编辑推荐:关于Java与.NET的讨论

网站导航:博客园首页  我的主页  新闻  闪存  小组  博问  社区  知识库

相关文章
相关标签/搜索