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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 思无邪

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提供的相关方法执行对象的销毁。