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的討論

網站導航:博客園首頁  我的主頁  新聞  閃存  小組  博問  社區  知識庫

相關文章
相關標籤/搜索