加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – WPF GarbageCollection中的高级调试建议

发布时间:2020-12-15 18:26:31 所属栏目:百科 来源:网络整理
导读:情况 我们正在运行一个不会释放内存的大型WPF应用程序.它不是真正的内存泄漏,因为内存将最终被释放.我知道通常情况下,这不会被认为是一个问题.不幸的是,它与WPF命令基础结构一起成为一个性能问题.有关详细信息,请参见下文. 发现 我们有自动测试,可以执行典型
情况

我们正在运行一个不会释放内存的大型WPF应用程序.它不是真正的内存泄漏,因为内存将最终被释放.我知道通常情况下,这不会被认为是一个问题.不幸的是,它与WPF命令基础结构一起成为一个性能问题.有关详细信息,请参见下文.

发现

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

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

?WinDbg没有显示任何对象准备好完成.

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

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

我们非常感谢任何关于调试这个问题的建议.

WPF CommandManager背景

WPF CommandManager包含用于提升CanExecuteChanged事件的WeakReferences(_requerySuggestedHandlers)的私有集合.处理CanExecuteChanged是非常昂贵的(特别是找到CanExecute的EventRoute,这显然是一个RoutedEvent).每当CommandManager感觉如果可以执行命令时,它会重新查询,它会遍历此集合并调用相应命令源上的CanExecuteChanged事件.

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

解决方法

我的一个应用程序也有同样的问题.在窗口的每一个开口我叫:
GC.GetTotalMemory(true);

这将迫使GC立即清理内存而无需等待.您可以在这里阅读更多关于此方法:

http://msdn.microsoft.com/en-us/library/system.gc.gettotalmemory.aspx

关于调用CanExecute的问题,我试图避免由于性能问题相同.相反,我在我的视图模型中使用属性,并将视觉元素的IsEnabled属性从XAML绑定到视图模型中的属性.以这种方式,整体性能得到改善,CanExecute呼叫已经消失.

我希望这将有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读