Как заставить .NET разгрузить неиспользуемую оперативную память? - PullRequest
8 голосов
/ 21 ноября 2011

Вот статистика моей программы после того, как она использовала память чрезвычайно интенсивно, потребляя максимум 6 ГБ, но затем сохраняя все на диск и оставляя очень мало места:

Screenshot

Обратите внимание, что почти все вышло за рамки и было собрано мусора - размеры кучи крошечные. И все же .NET сохраняет 181 МБ выделенных .

Я не против зарезервированных байтов, поскольку они занимают только адресное пространство. Но преданная память раздражает & ndash; даже если он находится только в файле подкачки, его все равно довольно много.

1 Ответ

7 голосов
/ 21 ноября 2011

Согласно CLR Inside Out - Обнаружена куча больших объектов CLR разделяет неиспользуемую выделенную память во время сборки мусора Gen 2. 2. 1003 *

Это означает, что вы можете либо ждать Gen2 сборка мусора происходит сама по себе, или вы можете принудительно выполнить ее, используя GC.Collect() - вам действительно нужно знать, что вы делаете, если вы выберете этот маршрут, однако, поскольку он мешает сборщикам мусора стандартные циклы сбора мусорачто может сильно повлиять на производительность:

  • Полная сборка мусора идет медленно, поэтому вы действительно не хотите делать это слишком часто
  • Запуск сборок мусора происходит чаще, чем стандартное расписаниепродвигать дополнительные объекты для более высоких поколений, что означает, что они не могут быть собраны, как только они будут

Насколько я знаю (из моего довольно ограниченного исследования), CLR не освободит выделенную память вдругие ситуации.

Вам также следует подумать, является ли это актом или нет.В действительности проблема:

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

Обновление: Усовершенствованная отладка .NET: управляемая сборка кучи и мусора подтверждает гипотезу о том, что память освобождается только во время сбора 2-го поколения:

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

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