小编el-*_*ino的帖子

WPF GarbageCollection中的高级调试建议

情况

我们正在运行一个大型WPF应用程序,它不会释放内存很长一段时间.它不是真正的内存泄漏,因为内存最终会被释放.我知道通常情况下,这不会被认为是一个问题.不幸的是,它与WPF指挥基础设施相结合成为一个性能问题.有关更详细的说明,请参见下文.

发现

我们有自动化测试,可以执行典型的用例.有些案例工作正常,并及时释放记忆.其他人正在占用内存,直到客户端最小化,打开一个新窗口或触发Gen2集合的其他一些条件.

•使用ANTS我们看到,对象没有GC Root,但是很多引用需要完成的其他对象.

•WinDbg未显示任何准备完成的对象.

•运行几个GC.Collect(),GC.WaitForPendingFinalizers()完全释放内存.

•我们知道哪种UI操作会导致高内存条件,但我们无法识别任何可疑代码.

我们希望有关于调试此类问题的任何建议.


WPF CommandManager背景

WPF CommandManager保存WeakReferences(_requerySuggestedHandlers)的私有集合以引发CanExecuteChanged事件.处理CanExecuteChanged成本非常高(尤其是找到EventRoute CanExecute,显然是一个RoutedEvent).只要CommandManager感觉像是在执行命令就可以执行,它会遍历此集合并CanExecuteChanged在相应的命令源上调用事件.

只要存在引用对象的GC句柄,就不会从该集合中删除WeakReferences.虽然尚未收集该对象,但CommandHelper会继续处理CanExecute这些元素的事件(ButtonBase或MenuItems).如果存在大量垃圾(如我们的情况),这可能导致CanExecute事件处理程序的调用数量极大,这会导致应用程序非常滞后.

c# wpf garbage-collection finalizer memory-profiling

11
推荐指数
1
解决办法
1282
查看次数