WPF内存泄露:CollectionViewSource.GetDefaultView导致Cache对象
在使用OpenExpressApp進行WPF應(yīng)用開發(fā)過程中遇到多個內(nèi)存泄漏的地方,昨天在WPF不明內(nèi)存泄露已解決,白頭發(fā)也沒了中講到了如何解決由于屬性跟蹤事件強引用導致的內(nèi)存泄漏問題,本篇介紹一下由于CollectionViewSource.GetDefaultView導致的內(nèi)存泄漏問題。
發(fā)現(xiàn)問題
還是昨天?WPF不明內(nèi)存泄露已解決,白頭發(fā)也沒了中說的場景,關(guān)閉模塊后仍舊保留了對象的引用,ANTS Memory Profiler 5查看對象引用圖如下
分析問題
使用Scitech memory profiler查看對象引用路徑,
查看ViewRecord對象的調(diào)用堆棧,如下:
查看后發(fā)現(xiàn)調(diào)用了一個CacheView方法,估計是把這個對象緩存起來了,使用Reflector查看源碼,
CollectionViewSource.GetDefaultView:
?
internal static CollectionView GetDefaultCollectionView(object source, bool createView){
ViewRecord record = DataBindEngine.CurrentDataBindEngine.GetViewRecord(source, DefaultSource, null, createView);
return (CollectionView) record.View;
}
其中DataBindEngine.CurrentDataBindEngine是一個靜態(tài)單例對象
?
?
internal static DataBindEngine CurrentDataBindEngine{
get
{
if (_currentEngine == null)
{
_currentEngine = new DataBindEngine();
}
return _currentEngine;
}
}
?
內(nèi)部調(diào)用了CacheView把對象緩存在單例DataBindEngine的ViewManager對象中。看了一下代碼,沒有看到如何清除緩存的地方(不知道有誰知道如何在程序中清除這個緩存?)
解決問題
查看GetDefaultCollectionView代碼可以發(fā)現(xiàn),其實內(nèi)部它是根據(jù)傳入對象的類型來決定生成一個什么CollectionView對象,由于我這邊傳入的肯定是IList,所以我修改GetDefaultView代碼為直接使用ListCollectionView對象,修改代碼如下:
??????????? //var collectionView = CollectionViewSource.GetDefaultView(viewData);? //inter call CacheView make memory leak
??????????? ListCollectionView collectionView = new ListCollectionView(viewData); ?
?修改后再使用內(nèi)存泄漏工具查找對象,這時你就再也找不到對象了:)
?
另:以上是我的一個分析以及解決辦法,雖然有事最好的解決辦法就是不用它,但是總感覺使用CollectionViewSource.GetDefaultView不應(yīng)該產(chǎn)生這個問題,否則誰還敢用,可能是我其它原因?qū)е碌疫€為發(fā)現(xiàn),上網(wǎng)搜索了也沒有查到什么有用資料,不知道誰有更好的辦法,請多指教!
?
?
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明:轉(zhuǎn)載自周金根 [ http://zhoujg.cnblogs.com/ ]
轉(zhuǎn)載于:https://blog.51cto.com/zhoujg/517969
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的WPF内存泄露:CollectionViewSource.GetDefaultView导致Cache对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shell 笔记一
- 下一篇: javascript获取asp.net后