【问题标题】:WPF not releasing memoryWPF不释放内存
【发布时间】:2011-08-10 00:42:04
【问题描述】:

我在我们的应用程序中遇到了一个问题,即当用户控制时内存没有释放 被卸载。这将使内存从 40MB 开始增加到 200MB 甚至更多。

为了模拟这个,

  1. 我创建了一个包含主窗口和用户控件的 wpf 项目
  2. 将 1000 个对象加载到放置在用户控件中的 wpf 数据网格中
  3. 在主窗口中放置了一个滚动查看器
  4. 单击显示按钮后,用户控件将加载到此滚动查看器中
  5. 单击“关闭”按钮后,用户控件将从 Scroll 浏览器的内容中移除

我在任务管理器中检查过,在将 1000 个对象加载到网格之前,内存消耗为 14MB。通过单击显示按钮加载后,它会增加到 70MB。但是当我单击关闭按钮从窗口中删除用户控件时,内存仅减少到 67MB。它不应该减少到 14BMB 或接近那个吗?

当我使用 ANTS 内存分析器检查这一点时,它显示即使在从窗口中删除用户控件后,这 1000 个对象仍保留在内存中。当用户控件从窗口中移除时(一旦滚动查看器内容属性设置为空),垃圾收集器不应该释放这些对象吗?

以下是我用于此的代码。我没有使用任何样式、数据模板或任何第三方控件,仅使用 WPF DataGrid 控件来加载数据。

背后的用户控制代码

public partial class UserControl1 : UserControl,IDisposable
{
    List<TestClass> list = null;

    public UserControl1()
    {
        InitializeComponent();
    }

    public void Dispose()
    {
        BindingOperations.ClearBinding(dgList, DataGrid.ItemsSourceProperty);
        list.Clear();
        GC.Collect();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        list = new List<TestClass>();

        for (int i = 0; i < 1000; i++)
        {
            TestClass obj = new TestClass();
            obj.Name = "test name";
            obj.Age = 34;

            list.Add(obj);
        }
        dgList.ItemsSource = list;
    }

}

public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }     
}

后面的主窗口代码

public partial class MainWindow : Window
{
    UserControl1 control = null;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        control.Dispose();
        scwContent.Content = null;
        control = null;

    }

    private void btnShow_Click(object sender, RoutedEventArgs e)
    {
        control = new UserControl1();
        scwContent.Content = control;
    }
}

谢谢。

【问题讨论】:

    标签: wpf memory garbage-collection wpfdatagrid


    【解决方案1】:

    你为什么要调用 GC?这不是必需的

    改变

    for (int i = 0; i < 1000; i++)        
    {            
        TestClass obj = new TestClass();
        ...
    

    到

    TestClass obj;
    for (int i = 0; i < 1000; i++)       
    {         
         obj = new TestClass();
         ...
    

    您可以将列表对象设置为 null .. 阅读此内容以了解将对象设置为 null Setting an object to null vs Dispose()

    【讨论】:

      【解决方案2】:

      垃圾收集器仅在需要内存时收集,而不是在引用设置为空时收集。

      (唯一例外:调用GC.Collect())

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-19
        • 2013-01-02
        • 2016-10-03
        • 2017-06-29
        • 2011-06-30
        • 2016-09-14
        • 2015-08-19
        相关资源
        最近更新 更多