我正在寻找一个寻找内存泄漏的WPF应用程序(使用ANTS Memory Profiler 5.1),并且我不断看到一些页面和控件在不应该占用时占用内存。
所以我转到对象保留图并看看是什么让它们保持不变,我会在每一页都看到这一点:
Object Retention Graph http://img683.imageshack.us/img683/3013/ants.jpg
问题是,我在每个页面上都将KeepAlive设置为false,并且我认为用户控件上不存在这样的属性。
谁能告诉我应该找什么?这甚至是内存泄漏还是WPF应用程序的正常行为?
答案 0 :(得分:8)
是的,根据您提供的内容,您有内存泄漏。当你找到引用链,并且它不在你的代码中时,最简单的方法就是... 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;
}
现在您了解规则。如果出现以下情况,对象将保留在内存中:
在调查之后,可能值得阅读有关MSDN上JournalEntry.KeepAlive属性的更多信息。
这种策略帮助我找到了许多与记忆相关的昆虫。希望它也能帮到你:)。
PS:如果您在查找此特定泄漏时遇到问题,可以粘贴最少的代码示例,以便我们重现它并为您提供更合适的答案。
干杯, Anvaka
答案 1 :(得分:5)
我有与蚂蚁记忆分析器相同的问题和相同的图表。
该应用程序使用NavigationWindow
来托管一些WPF页面,并使用此代码隐藏进行导航:
NavigationService.Navigate( new Page1());
问题是由日志保存在内存中的多个页面创建的,无法进行垃圾回收。
我所做的是用普通窗口替换NavigationWindow
,使用UserControls替换Pages并在窗口内交换用户控件,就像它们是页面一样。
关于如何在谷歌中执行此操作有很多示例。
删除所有NavigationService.Navigate
调用后,我终于可以使用Ants内存分析器对所有已关闭的页面进行垃圾收集。