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

推荐订阅源

V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
S
SegmentFault 最新的问题
D
DataBreaches.Net
博客园_首页
罗磊的独立博客
B
Blog
T
Threat Research - Cisco Blogs
C
Cisco Blogs
GbyAI
GbyAI
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
G
GRAHAM CLULEY
H
Help Net Security
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
SecWiki News
SecWiki News
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Schneier on Security
Schneier on Security
T
The Exploit Database - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
T
Tor Project blog
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
H
Hacker News: Front Page
V
V2EX
Security Latest
Security Latest
Cloudbric
Cloudbric
Simon Willison's Weblog
Simon Willison's Weblog
Attack and Defense Labs
Attack and Defense Labs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Proofpoint News Feed
博客园 - 三生石上(FineUI控件)
NISL@THU
NISL@THU
S
Secure Thoughts
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
P
Palo Alto Networks Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Docker
Google DeepMind News
Google DeepMind News
Webroot Blog
Webroot Blog

博客园 - 思无邪

Silverlight内存泄露(八)样式 Silverlight内存泄露(七)Command Silverlight内存泄露(五)MEF等Ioc框架引起内存泄露-PartCreationPolicy 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框架引起内存泄露-ExportLifetimeContext
思无邪 · 2011-04-15 · via 博客园 - 思无邪

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

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

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

内存泄露系列阅读提示:

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

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

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

ExportLifetimeContext使用不当造成内存泄露

ExportLifetimeContext 需要调用Dispose方法释放由MEF管理的对象,否则对象不会被释放。

MSDN:

Disposing of a ExportLifetimeContext(Of T) object calls the referenced method to release its associated export.

Call Dispose when you are finished using the ExportLifetimeContext(Of T). The Dispose method leaves the ExportLifetimeContext(Of T) in an unusable state. After calling Dispose, you must release all references to the ExportLifetimeContext(Of T) so the garbage collector can reclaim the memory that theExportLifetimeContext(Of T) was occupying. 

可以看到ViewModel存在多个实例,可能出现了内存泄露。

clip_image002

经过分析找出发生内存泄露的对象图:

clip_image004

可以看到MEF的DisposableReflectionComposablePart一直保持着ViewModel的引用,造成不能释放ViewModel。

MVVM使用自定义导航,代码: 

[Export]
public class CompositionNavigationContentLoader : INavigationContentLoader
{
public CompositionNavigationContentLoader()
{
}
[ImportMany(
typeof(IView))]
public IEnumerable<ExportFactory<IView, IViewMetadata>> ViewExports { getset; }
[ImportMany(
typeof(IViewModel),RequiredCreationPolicy = CreationPolicy.Any)]
public List<ExportFactory<IViewModel, IViewModelMetadata>> ViewModelExports { getset; }
[ImportMany(
"lazy"typeof(IViewModel), RequiredCreationPolicy = CreationPolicy.Any)]
public List<Lazy<IViewModel, IViewModelMetadata>> LazyViewModelExports { getset; }
public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri, AsyncCallback userCallback, object asyncState)
{
var viewModelMapping 
= ViewModelExports.FirstOrDefault(o => o.Metadata.Key.Equals(relativeUri.Host, StringComparison.OrdinalIgnoreCase));
//ViewModel
var viewModelFactory = viewModelMapping.CreateExport();
viewModel 
= viewModelFactory.Value as IViewModel;
viewModelFactory.Dispose();//释放对象
//View
var viewFactory = viewMapping.CreateExport();
view 
= viewFactory.Value as Control;
viewFactory.Dispose(); 
//释放对象
//绑定、导航
view.DataContext = viewModel;
var values 
= viewModelMapping.Metadata.GetArgumentValues(targetUri);
viewModel.OnNavigated(values); 

}

如果不加上viewModelFactory.Dispose();

对象MEF创建的对象不会被回收,VIew、ViewModel及其引用的资源都一直保持到程序关闭。 

结论

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

b) 内存泄露都有上下文,只有特定上下文中托管代码才可能产生内存问题。

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