2

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

每个游戏我都有这样的组件:

  • 主视图 [CreationPolicy.Shared]
    • View1 [CreationPolicy.Shared]
    • ViewN [CreationPolicy.Shared]
  • MainViewModel [CreationPolicy.Shared]
    • ViewModel1 [CreationPolicy.Shared]
    • ViewModelN [CreationPolicy.Shared]

通过调用创建的每个“视图”(main、1st、2nd ...)

_serviceLocator.GetInstance<MainView>();

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

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

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

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

4

1 回答 1

0

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

由于您没有在您的问题中提供此类信息,我会指出这种泄漏的一个非常可能的原因是您的对象实现了IDisposable. MEF 保留对一次性对象的引用而不释放它们存在一个已知问题。如果确实如此,您可以查看此问题以获取更多详细信息和可能的解决方案:MEF 保留对 NonShared IDisposable 部件的引用,不允许它们被 GC 收集。另一种可能性是您的一个导入配置为允许重组 - 在这种情况下,MEF 还将保留对您的对象的引用。

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

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

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

于 2013-07-19T20:42:47.083 回答