从区域中删除视图时内存泄漏

时间:2013-04-19 17:39:23

标签: .net wpf mvvm prism mef

我创建了游戏管理器,可以使用PRISM MEF在区域中选择不同的游戏。 “MainRegion”中有一个静态shell和动态内容。每个游戏都是独立的模块(程序集),当我获得实例时,它为每个游戏分配大约20-30 MB。

我为每场比赛都有这样的组件:

  • MainView [CreationPolicy.Shared]
    • View1 [CreationPolicy.Shared]
    • ViewN [CreationPolicy.Shared]
  • MainViewModel [CreationPolicy.Shared]
    • ViewModel1 [CreationPolicy.Shared]
    • ViewModelN [CreationPolicy.Shared]

通过调用

创建的每个“视图”(主要,第1,第2 ......)
_serviceLocator.GetInstance<MainView>();

每个“视图”都具有以下属性

[Import(AllowRecomposition = false)]
public MainViewModel ViewModel //example for MainView
{
    get { return this.DataContext as MainViewModel; }
    set { this.DataContext = value; }
}

当我想要更改游戏时,我会从MainView删除MainRegion,但它不会创建新实例,因为PartCreationPolicy设置为Shared,但如果我使用NonShared删除实例后会出现内存泄漏。

如何在我的应用程序中修复此内存泄漏?

1 个答案:

答案 0 :(得分:0)

解决泄漏问题的关键是首先通过使用内存分析器并确定对象保存在内存中的原因以及哪个对象包含对它们的引用来理解它。

由于您未在问题中提供此类信息,我将指出此泄漏的一个可能原因是您的对象实施IDisposable。 MEF存在一个已知问题,即保留对一次性物体的引用而不释放它们。如果情况确实如此,您可以查看此问题以获取更多详细信息和可能的解决方案:MEF keeps reference of NonShared IDisposable parts, not allowing them to be collected by GC。另一种可能性是你的一个导入被配置为允许重构 - 在这种情况下,MEF也将保留对你的对象的引用。

您还应该记住,GC仅在需要时执行垃圾收集,而不一定在删除实例后立即执行垃圾收集。您可以自己调用垃圾收集器以确保对象确实保存在内存中:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

如果您的对象不是一次性的并且没有允许重新组合的导入,那么对它们的引用很可能由您自己的代码保存,并且您将必须分析您的应用程序以找出谁。为此,我建议使用ANTS Memory Profiler