WPF没有释放内存

时间:2011-04-21 04:54:36

标签: wpf memory garbage-collection wpfdatagrid

我的应用程序中存在一个问题,即用户控制时不会释放内存 正在卸载。这将从40MB开始增加内存,最终达到200MB甚至更多。

要模拟这个,

  1. 我创建了一个包含主窗口和用户控件的wpf项目
  2. 将1000个对象加载到放置在用户控件中的wpf数据网格
  3. 滚动查看器放在主窗口中
  4. 单击“显示”按钮后,将在此滚动查看器中加载用户控件
  5. 单击“关闭”按钮后,用户控件将从Scroll viwer的内容中删除
  6. 一旦我检查了任务管理器,在将1000个对象加载到网格之前,内存消耗为14MB。一旦点击显示按钮加载它就会增加到70MB。但是当我单击关闭按钮从窗口中删除用户控件时,内存仅减少到67MB。它不应该减少到14BMB或接近那个??

    当我使用ANTS内存分析器检查时,它显示即使从窗口中删除用户控件后,1000个对象仍保留在内存中。从窗口中删除用户控件时,垃圾收集器是否应该释放这些对象(一旦Scroll viewer Content Property设置为null)?

    以下是我用于此的代码。我没有使用任何样式,数据模板或任何第三方控件,只使用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;
        }
    }
    

    感谢。

2 个答案:

答案 0 :(得分:0)

你为什么要打电话给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()

答案 1 :(得分:0)

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

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