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

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

2 голосов
/ 27 августа 2009

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

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

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

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

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

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

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

Обновление

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

Ответы [ 5 ]

6 голосов
/ 27 августа 2009

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

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

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

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

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

5 голосов
/ 27 августа 2009

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

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

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

2 голосов
/ 27 августа 2009

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

0 голосов
/ 12 октября 2012

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

0 голосов
/ 27 августа 2009

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

SysInternals Process Explorer

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...