我的WPF导航中是否有内存泄漏?

Bra*_*don 7 .net wpf memory-leaks

我正在寻找一个寻找内存泄漏的WPF应用程序(使用ANTS Memory Profiler 5.1),我不断看到一些页面和控件占用内存.

所以我转到对象保留图并看看是什么让它们保持不变,我会继续看到每个页面:

对象保留图http://img683.imageshack.us/img683/3013/ants.jpg

问题是,我在每个页面上都将KeepAlive设置为false,并且我认为用户控件上不存在这样的属性.

谁能告诉我我应该找什么?这甚至是内存泄漏还是WPF应用程序的正常行为?

Anv*_*aka 9

是的,根据您提供的内容,您有内存泄漏.当你找到引用链,并且它不在你的代码中时,最简单的方法就是... Reflector.

图像说:JournalEntryKeepAlive._keepAliveRoot字段包含对象的引用.让我们进入Reflector,看看这个家伙是如何与我们的对象挂钩的.

这一次很容易,所有的痕迹都会导致NavigationService.MakeJournalEntry()功能再到NavigationService.IsContentKeepAlive().这里是:

internal bool IsContentKeepAlive()
{
    bool keepAlive = true;
    DependencyObject dependencyObject = this._bp as DependencyObject;
    if (dependencyObject != null)
    {
        keepAlive = JournalEntry.GetKeepAlive(dependencyObject);
        if (!keepAlive)
        {
            PageFunctionBase base2 = dependencyObject as PageFunctionBase;
            bool flag2 = !this.CanReloadFromUri;
            if ((base2 == null) && flag2)
            {
                keepAlive = true;
            }
        }
    }
    return keepAlive;
}
Run Code Online (Sandbox Code Playgroud)

现在你知道了规则.在以下情况下,对象保留在内

  • 它不是一个依赖对象;
  • 附属的Propery JournalEntry.KeepAlive是真的;
  • 它不是PageFunction,也不能从Uri重新加载.

在此调查之后,可能值得阅读有关MSDN上的JournalEntry.KeepAlive属性的更多信息.

这种策略帮助我找到了许多与记忆相关的昆虫.希望它也可以帮助你:).

PS:如果您在查找此特定泄漏时遇到问题,可以粘贴最少的代码示例,以便我们重现它并为您提供更合适的答案.

干杯,安瓦卡

  • 你实际改变了什么让这个页面被垃圾收集? (3认同)

小智 6

我和Ants内存分析器有同样的问题和相同的图表.该应用程序使用a NavigationWindow来托管一些WPF页面,并使用此代码隐藏进行导航:

NavigationService.Navigate( new Page1());
Run Code Online (Sandbox Code Playgroud)

问题是由日志保存在内存中的多个页面创建的,并且不能进行垃圾回收.

我做的是NavigationWindow用一个普通的窗口替换,带有UserControls的Pages和窗口内的交换用户控件,就像它们是页面一样.关于如何在谷歌中执行此操作有很多示例.删除所有NavigationService.Navigate调用后,我终于可以使用Ants内存分析器对所有已关闭的页面进行垃圾回收.

  • 聪明.但是很多工作.此外,您不必开发自己的导航服务吗?我试过这样做,这真的很痛苦. (2认同)