动态加载和卸载内容时,WPF应用程序会泄漏内存

时间:2018-07-28 10:29:42

标签: wpf memory-leaks

我正在动态地在WPF应用程序中加载和卸载内容,以启用可扩展的框架来向用户呈现大量的异构数据。

有时,当丢弃动态加载的内容时,会导致内存泄漏。例如,在名为Workspace的框架中显示的SyncFusion GridControl如下:

ControlTemplate template = (ControlTemplate)Workspace.FindResource("SfGridTemplate");
DependencyObject root = template.LoadContent();
Workspace.Content = root;
GridControl dataItemsGrid = (GridControl)LogicalTreeHelper.FindLogicalNode(root, "SfGridControl");
....

在Xaml中定义资源SfGridTemplate的地方:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:local="clr-namespace:GCTest"
                    xmlns:sf="http://schemas.syncfusion.com/wpf">
  <ControlTemplate x:Key="SfGridTemplate">
    <Grid>
      <sf:GridControl Name="SfGridControl" ...>
        <sf:GridControl.Resources>
          ....
        </sf:GridControl.Resources>
      </sf:GridControl>
    </Grid>
  </ControlTemplate>
</ResourceDictionary>

加载后,我打印出窗口的逻辑树(但请参见下面的PS):

GCTest.MainWindow
  System.Windows.Controls.Grid
    ....
    System.Windows.Controls.Frame Workspace
      System.Windows.Controls.Grid
        Syncfusion.Windows.Controls.Grid.GridControl

我现在通过Workspace.Grid.Children.RemoveAt(0)从框架中删除GridControl并再次打印出逻辑树:

  GCTest.MainWindow
    System.Windows.Controls.Grid
      ....
      System.Windows.Controls.Frame Workspace
        System.Windows.Controls.Grid

显然,GridControl对象已被删除。但是,Visual Studio中的堆诊断仍然显示:

  Syncfusion.Windows.Controls.Grid.GridControl  1   62,452  135,664

带有拜占庭式的“根目录路径”列表,其中涉及Hashtable,ListDictionary,DictionaryNode,HybridDictionary ...对象,这些我无法理解。强制使用GC.Collect或GridCOntrol.Dispose对此行为没有影响。

最终结果是,当应用程序加载和卸载某些UI元素时,它似乎会泄漏内存。如上所述,SyncFusion GridControl会导致泄漏,但例如SyncFusion SfChart不会。

寻找类似问题后,我已经消除了内存泄漏的可能原因:事件处理程序,计时器,数据绑定(上述测试应用程序中没有使用这些处理程序)。

(1)为什么GridControl对象显然是由某个根对象持有的?

(2)如何删除该引用,以便可以回收内存?

可能有一个相关的奇数:LogicalTreeHelper.GetChildren(Workspace)(即我将内容加载到其中的Frame的子代)始终返回一个空列表,我必须执行Workspace.Content才能在列表中查看DataGrid控件。逻辑树。

0 个答案:

没有答案