惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
人人都是产品经理
人人都是产品经理
H
Heimdal Security Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
A
About on SuperTechFans
V2EX - 技术
V2EX - 技术
小众软件
小众软件
博客园 - Franky
博客园 - 司徒正美
P
Privacy International News Feed
爱范儿
爱范儿
U
Unit 42
博客园 - 叶小钗
The Hacker News
The Hacker News
C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Simon Willison's Weblog
Simon Willison's Weblog
N
News and Events Feed by Topic
D
Docker
T
Threatpost
MongoDB | Blog
MongoDB | Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Help Net Security
L
LINUX DO - 最新话题
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
A
Arctic Wolf
Spread Privacy
Spread Privacy

博客园 - 思无邪

Silverlight内存泄露(八)样式 Silverlight内存泄露(七)Command Silverlight内存泄露(六)MEF等Ioc框架引起内存泄露-ExportLifetimeContext Silverlight内存泄露(四)解决内存泄露 Silverlight内存泄露(二)检测内存泄露 从火狐放弃依据特性更新版本说起 Silverlight内存泄露(二)解决内存泄露之Dispose误用 Silverlight内存泄露(一)序 Silverlight IReader阅读器第二版 silverlight阅读器——面向领域的浏览器(二)——Silverlight阅读器架构 silverlight阅读器——起源面向领域的浏览器——概念 silverlight异步陷阱(二)循环 silverlight 异步陷阱(一)不能Remove事件处理程序 IReader Silverlight电子阅读器介绍开源项目 silverlight在线阅读器(二):为silverlight增加gb2312编码 silverlight在线阅读器(一):介绍 新建立一个类似于CuteEditor的项目,希望有人参加。发布一个测试版本的dll 从控件开发的角度看几个editor控件,Freetextbox,radtoolbar,abouteditor,cuteeditor 想做一个关于word解析和HtmlEditor的项目,希望有人加入 cuteEditor6.0的破解方式与Cuteeditor6.0的脚本调试
Silverlight内存泄露(五)MEF等Ioc框架引起内存泄露-PartCreationPolicy
思无邪 · 2011-04-14 · via 博客园 - 思无邪

对象的创建可以使用new,也可以使用IOC架如:castle、MEF等,IOC创建的对象的生命周期,可能IOC负责管理,使用框架的开发者如果不弄清楚可能会造成内存泄露问题。

这些内存泄露问题并不是IOC框架的bug,只是开发者使用不当或者不注意造成的内存泄露问题。

以MEF为例说明我碰到的两种内存泄露问题。

内存泄露系列阅读提示:

一摸一样的对象图,有时候我们可以认为它是内存泄露,有时候又认为它不是内存泄露,这一切只是由于上下文不同,这一系列文章中ANTS Memoery Profle截图都是有特定上下文,单独看完全没有意义。如何确定是内存泄露?可以参考前面的文章。

对象以图的形式存在,Ants Memory Profile为了分析方便把这些图处理为树,让我们可以把注意力集中到分析的对象。但我们必须明白内存中对象关系构成图,也就是说ANTS的树状图只是内存中对象分布的一个局部,分析内存泄露时必须有全局观念,需要相关的几张图一起看,即使一张图也要整体看,这样才能分析内存泄露问题。

由于看一张图没什么意义,如果把多张图都贴出来,这文章就太难写了,即使多张图都贴出来,也不一定能表达清楚,分析内存泄露最重要的是经验。接下来的几篇会减少甚至不用这ANTS图。

PartCreationPolicy使用不当引起内存泄露

Shared:对象以Singleton方式创建。

Non Shared:每次请求时创建新对象。

Any Be default, CompositionContainer will use Shared, unless the ComposablePart or importer requests NonShared。默认值

在使用不同的组合方式时,PartCreationPolicy有不同的默认值,因此尽量不要使用默认值。

看下面的程序:

NavigationCommand:由于多个View页面都有需要导航,把导航都放到类NavigationCommand中,恰恰是这一做法引出了内存泄露问题。

[Export(typeof(NavigationCommand))]public class NavigationCommand

{

private RelayCommand<string> readBookComamand = null;public RelayCommand<string> ReadBookComamand

{

get

{

if (navigatToContentCommand == null)

{

navigatToContentCommand 

= new RelayCommand<string>

(

=>

{

//
},

=> !string.IsNullOrWhiteSpace(p)

);

}

return readBookComamand;

}

}

}

ViewModle

[ViewModelExport(typeof(BookPageSearcheViewModle), "BookPageSearche")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class BookPageSearcheViewModle: NavViewModel
{
public RelayCommand<string> ReadBookComamand
{
get
{
return NavigationCommand. ReadBookComamand;
}
}
}
public abstract class NavViewModel : ViewModelBase, IViewModel
{
/// <summary>
/// The navigation service allows you to navigate to an other ViewModel.
/// </summary>
[Import]
public INavigationService NavigationService { getset; }
[Import]
public NavigationCommand NavigationCommand
{
get;
set;
}
}

View

[ViewExport(ViewModelContract = typeof(BookPageSearcheViewModle))]
public partial class BookPageSearcheView: Page, IView
{
public BookPageSearcheView ()
{
InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (this.DataContext is ICleanup)
{
((ICleanup)
this.DataContext).Cleanup();
}
}
}
}

上例中NavigationCommand默认以Shared方式创建。

ANTS Memory Profiel 产生内存泄露的对象图:

5

可看出:BookPageSearcheViewModle 、Mef都引用了NavigationCommand,导致NavigationCommand没有被释放产生了内存泄露,在此只看MEF这一条路径。

我在处理这个内存泄露时太专注于BookPageSearcheViewModle对readBookCommand的引用了,而没有全面看这些图,断开BookPageSearcheViewModle对readBookCommand引用是最简单的处理方法,但是在处理其他ViewModel的时候会发现太多的Command需要处理,这时候才认识到断开引用的点错了。

因此一定要谨慎全面的看对象图,一个路径上包含n个点,断开任何点都能解决这个对象的泄露问题,但是一个程序有N个对象,这种只着眼当前对象的处理方式不能从根本上解决问题,必须找到内存泄露的根源

clip_image002

解决MEF这个泄露问题,最简单的是加上:[PartCreationPolicy(CreationPolicy.NonShared)]

还可以使NavViewModel类实现所有Command,把组合转换为继承,断开长引用。

结论

a) 不要盲目使用第三方框架。

b) 设计时组合优先于继承,但组合更容易产生内存泄露,因为任何一方如果是长时间存活,内存就不会被释放。继承则无这个问题。

c) 注意由IOC创建的对象生命周期,如果IOC创建的对象由容器管理生命期,可能需要调用IOC提供的相关方法执行对象的销毁。

e)MVVM 比Code behind 方式更容易产生内存问题。V、VM双向引用关系,更可能造成内存不被释放