Утечка памяти .NET?

У меня есть MDI с дочерней формой. Дочерняя форма имеет DataGridView в нем. Я загружаю огромное количество данных в представление сетки данных. Когда я закрываю дочернюю форму, вызывается метод удаления, в котором я удаляю datagridview

    this.dataGrid.Dispose();
    this.dataGrid = null;

Когда закрываю форму, память не уходит. Я использую профилировщик памяти .NET для отслеживания использования памяти. Я вижу, что использование памяти увеличивается, когда я первоначально загружаю сетку данных (как и ожидалось), а затем становится постоянным, когда загрузка завершена.

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

Что здесь происходит? Есть утечка памяти? Или мне нужно принудительно запустить сборщик мусора?

Дополнительная информация:

Когда я закрываю форму, мне больше не нужна информация. Вот почему я не держу ссылку на данные.

Обновить

От меня требуется загрузить все данные сразу. Использование памяти становится очень высоким, когда данных много, поэтому мне интересно, делаю ли я что-то не так, и сборщик мусора не запускается, но, с другой стороны, когда я смотрю на профилировщик, он показывает, что когда он берет снимок потребление памяти уменьшается. Поэтому я не могу понять, что происходит.


person SA.    schedule 27.08.2009    source источник
comment
Откуда вы загружаете данные / к какому объекту привязаны?   -  person RichardOD    schedule 27.08.2009
comment
Я привязываю его к DataView   -  person SA.    schedule 27.08.2009


Ответы (5)


Установка переменной в null не вызывает волшебного вызова сборщика мусора. Сборка мусора - дорогостоящий процесс, и его следует избегать за исключением случаев крайней необходимости, поэтому сборщик запускается только по расписанию или в случае необходимости.

Если вам действительно нужно убедиться, что память освобождена, вручную вызовите сборщик мусора после того, как вы обнулили свой DataGrid:

this.dataGrid.Dispose();
this.dataGrid = null;
GC.Collect();

Однако, как заметил Мэтью Шарли, имеет ли значение, удерживает ли среда CLR эту память? Если вы принудительно освободите его, то в следующий раз, когда ваш DataGrid будет заполнен, CLR потребуется перераспределить тот же объем памяти, что происходит медленно.

Если ваш DataGrid не потребляет почти или больше физической памяти на вашем компьютере, оставьте среду CLR в покое - она ​​почти наверняка лучше всех знает, когда дело доходит до управления памятью.

person Ian Kemp    schedule 27.08.2009
comment
Другое дело, даже если память удерживается, если на нее ничего не ссылается, она (в конечном итоге) просто выгружается и все равно остается на вашем жестком диске, пока сборщик мусора не запустится и не соберет ее. - person Matthew Scharley; 27.08.2009

Это нормально. При необходимости сборщик мусора запускается в свое время. Тот факт, что он возвращается в нормальное состояние при принудительном включении сборщика мусора, означает, что нет утечек или постоянных ссылок, поддерживающих вещи.

Настоящий вопрос: нужно ли запускать сборщик мусора? Вы используете больше оперативной памяти, чем имеете физически? Если нет, то действительно ли имеет значение, если вы используете кучу физической ОЗУ, которая больше ни в чем не нуждается?

Еще один действительно хороший вопрос: действительно ли вам нужно загружать все данные в приложение сразу? Но без дополнительной информации ответить на этот вопрос невозможно.

person Matthew Scharley    schedule 27.08.2009

Сборка мусора не происходит только потому, что вы обнуляете ссылку. Если ваш объект больше не является ссылкой, он будет собран в какой-то момент. Тот факт, что он все еще существует некоторое время, не означает, что у вас есть утечка памяти. Более того, даже если вы выполняете сборку мусора, память не обязательно будет немедленно передана ОС, поэтому вы можете не увидеть падения использования памяти для приложения.

person Brian Rasmussen    schedule 27.08.2009

GC.WaitForPendingFinalizers(); - это мне помогло.

person Vil    schedule 12.10.2012

Это полезный инструмент для отслеживания утечек памяти:

SysInternals Process Explorer

person Richard Lucas    schedule 27.08.2009
comment
-1 Профилировщик памяти .NET (который OP использует прямо сейчас) намного лучше для поиска утечек памяти в управляемом коде. - person Niki; 14.03.2010