WPF не освобождает память - PullRequest
3 голосов
/ 21 апреля 2011

У меня есть проблема в нашем приложении, когда память не освобождается, когда пользовательские элементы управления выгружаются.Это увеличит объем памяти, начиная с 40 МБ и заканчивая 200 МБ и более.

Чтобы смоделировать это,

  1. Я создал проект wpf, который имеет главное окно и пользовательский элемент управления
  2. загрузил 1000 объектов в сетку данных wpf, которая помещается в пользовательский элемент управления
  3. Средство просмотра прокрутки помещается в главное окно
  4. Пользовательский элемент управления загружается в это средство просмотра прокруткинажата кнопка показа
  5. Пользовательский элемент управления удаляется из содержимого окна просмотра прокрутки после нажатия кнопки «Закрыть»

Как только я проверил с помощью диспетчера задач, перед 1000 объектовзагружаются в сетку, потребление памяти составляет 14 МБ.После загрузки, нажав на кнопку шоу, он увеличивается до 70 МБ.Но когда я нажимаю кнопку «Закрыть», чтобы удалить пользовательский элемент управления из окна, объем памяти уменьшается до 67 МБ.Разве это не должно уменьшиться до 14BMB или чего-то подобного ??

Когда я проверил это с помощью профилировщика памяти ANTS, он показывает, что 1000 объектов остаются в памяти даже после удаления пользовательского элемента управления из окна.Разве сборщик мусора не должен освобождать эти объекты, когда пользовательский элемент управления удаляется из окна (если свойство содержимого средства просмотра прокрутки установлено в значение 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 голосов
/ 21 апреля 2011

Сборщик мусора собирается только тогда, когда требуется память, а не тогда, когда ссылки установлены на ноль.

(Единственное исключение: звонок GC.Collect())

0 голосов
/ 21 апреля 2011

Почему вы пытаетесь позвонить в 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. Прочитайте это для понимания установки объектов в нуль Установка нулевого объекта против Dispose ()

...