【问题标题】:WPF RichTextBox tab selection eating up system memory!WPF RichTextBox 选项卡选择占用系统内存!
【发布时间】:2009-08-14 14:08:08
【问题描述】:

我在 WPF / MVVM 中有一个 TabControl,它绑定到 ObservableCollection 之上的 ItemsSource。每个选项卡都有自己的集合和与图像、Richtextboxes 和用户输入框等组件的绑定,并且一切似乎都运行良好。

但是,我注意到每次切换选项卡时,它都会使用大约 100k 的系统内存,而这些内存永远不会被回收!如果我按住 ctrl-tab 循环浏览所有选项卡,我可以在一分钟内使用 200 兆内存。

现在 - 我创建了一个只有一个选项卡控件的空白 WPF 应用程序,它还为每个选项卡开关使用内存(虽然少得多)。这只是一些 .NET 错误还是一个功能?也许它存储了一个面包屑轨迹,也许它用于调试(虽然我是在发布模式下编译的)。

如何恢复我的记忆?或者更好的是,不会因为标签切换而丢失内存?

【问题讨论】:

    标签: wpf memory-leaks richtextbox tabs


    【解决方案1】:

    这解决了我的问题: http://blingcode.blogspot.com/2010/10/memory-leak-with-wpfs-richtextbox.html

    基本上为每个 RichTextBox 添加两个属性 :) :) IsUndoEnabled="False" UndoLimit="0"

    【讨论】:

      【解决方案2】:

      您可能想检查是否有遗留事件处理程序。

      如果你在其他控件中注册了一个事件,垃圾收集器不会收集不再需要的对象,因为可以说事件仍然是附加的。

      所以如果你在代码后面的某处注册了 Loaded

      public ParentEditor()
      {
          InitializeComponents();
          control.Loaded += OnControlLoaded;
      }
      

      或在 XAML 或 ParentControl 中

      <Control Loaded="OnControlLoaded" />
      

      你基本上有两种解决方案来解决这个问题:

      解决方案 1 - 在不再需要事件处理程序时删除它们:

      您可能希望在卸载父控件时删除此处理程序,如下所示:

      public ParentEditor()
      {
          InitializeComponents();
          control.Loaded += OnControlLoaded;
          
          this.Unloaded += OnParentUnloaded;
      }
      
      void OnParentUnloaded(object sender, RoutedEventArgs e)
      {
          //Remove unloaded event
          this.Unloaded -= OnParentUnloaded;
          
          //Remove event from child control
          control.Loaded -= OnControlLoaded;        
      }
      

      您当然也可以使用子控件的 Unloaded 事件.. 这取决于您..

      解决方案 2 - 使用 Wea​​kEvent 模式:

      另一个事件解决方案是WeakEvent 模式,它绕过了这个问题。

      为什么要实施 WeakEvent 模式?

      监听事件会导致 内存泄漏。典型技术 听一个事件就是使用 特定于语言的语法 将处理程序附加到 a 上的事件 资源。例如,在 C# 中, 语法是:source.SomeEvent += new SomeEventHandler(MyEventHandler)。

      这种技术创造了一个强大的 从事件源引用到 事件监听器。通常情况下,附加 侦听器的事件处理程序导致 听者有一个对象 受对象影响的寿命 源的生命周期(除非 事件处理程序被显式删除)。 但在某些情况下,您可能 想要对象的生命周期 监听器只能由 其他因素,例如是否 当前属于视觉树 的应用程序,而不是由 源的生命周期。每当 源对象的生命周期超出 侦听器的对象生命周期, 正常的事件模式导致 内存泄漏:监听器被保留 比预期的寿命更长。

      在任何一种情况下,祝你好运.. 很难找到像您正在经历的泄漏!

      【讨论】:

      • 感谢您的建议 - 非常有用!但是对于 MVVM,甚至不使用事件处理程序。 viewmodel 对 gui 一无所知,只公开命令 gui 挂钩。
      【解决方案3】:

      好建议,但最后我认为可绑定文本块比富文本框更有用、更简单。我从未发现导致泄漏的原因 - 但它肯定在 bindablerichtextbox 代码中(每次切换选项卡时都会调用 OnInitialized,这超出了我的控制范围)。

      泄漏消失了,由于使用了更简单的可绑定文本块,我的应用运行得更快了。

      【讨论】:

        猜你喜欢
        • 2022-08-15
        • 2014-11-02
        • 2013-11-20
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-10
        相关资源
        最近更新 更多