Когда память, выделенная процессом .NET, возвращается обратно в Windows - PullRequest
20 голосов
/ 09 марта 2011

Настройка

.NET выделяет память для кучи каждого поколения (0, 1, 2, LOH) в сегментах, чтобы получить непрерывный блок памяти при запуске и при попытке удовлетворить запрос на выделение после коллекции.

Эта память, выделенная для каждой кучи, вероятно, будет выравниваться по мере «прогрева» приложения, за исключением потенциально второго поколения и кучи больших объектов. Во время сборки мусора каждая куча (0, 1, 2) очищается и сжимается, за исключением большой кучи объектов (LOH), которая только что очищается.

Я понимаю, что часть «развертки» коллекции означает, что сборщик мусора определяет, какие объекты больше не являются корневыми и доступны для сбора (или завершения), и что «компактный» означает, что адреса, которые все еще живы в куче реорганизованы таким образом, чтобы в доступной оставшейся куче было больше непрерывной памяти.

Поскольку бюджет для каждого сегмента в куче превышен, .NET выделит другой сегмент для выполнения выделений, если сможет.

Вопрос

Мой вопрос сводится к тому, что происходит с этой памятью в каждой куче, то есть больше не будет использоваться приложением (зафиксировано), но все еще зарезервировано .NET? Когда он вернется в ОС? .

Я полагаю, что это тот сценарий, когда процесс может показаться потребляющим много памяти (виртуальный размер довольно большой, но частных байтов мало), но при проверке его кучи в основном свободного места, В качестве другого предостережения, общий размер кучи также может быть весьма небольшим и не учитывать объем памяти, потребляемый процессом.

Там нет заблокированного финализатора, и все выглядит здоровым для процесса - он мог работать неделями, прежде чем он вызвал предупреждение монитора (например,).

Попытка дальнейшего разъяснения вопроса, если вы прочитаете Tess .NET Memory Management - аналог ресторана , если таблицы являются сегментами кучи, теряет ли ресторан когда-либо таблицы (например, свободные сегменты кучи)?

Редактировать

  1. Удалена запутанная ссылка на рабочий набор и кур
  2. Добавлена ​​ссылка на аналогию с рестораном Tess

Ответы [ 2 ]

10 голосов
/ 09 марта 2011

Мой ответ - это не имеет значения. ОС предоставляет приложение (в пределах которого выполняется среда выполнения .NET) виртуальная память . Это не «настоящая» память. ОС может размещать каждую страницу виртуальной памяти где угодно - на процессоре, в основной памяти, на диске. Таким образом, приложение может использовать больше памяти, чем объем оперативной памяти в системе, и ОС скопирует необходимые биты на диск и с него, чтобы приложение продолжало работать (по модулю определенных адресов и технических ограничений).

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

Разъяснение по электронной почте от Тесс : (выделено мое)

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

  1. Выделение для сегмента - это виртуальное выделение , что означает, что, хотя мы резервируем виртуальную память , мы только фиксируем то, что мы фактически используем, поэтому личных байтов , используемых для сегмента, не совпадают с размером сегмента, это означает, что после GC ваши личные байты будут уменьшаться, а ваши виртуальные байты останутся прежними.

  2. Когда сегмент больше не используется, т. Е. Если вам случается с GC все в сегменте, так что он больше не содержит объектов .net, виртуальное выделение возвращается обратно в ОС.

Если принять это на веру, то сегменты кучи (столы в ресторане) будут возвращены обратно в ОС.

0 голосов
/ 14 марта 2011

Я не знаю ответа на этот вопрос, но подозреваю, что .NET не освобождает свои кучи до тех пор, пока не завершится процесс (и, возможно, при выгрузке AppDomain, по-видимому). Это только на основе моего наблюдения счетчиков памяти .NET памяти perfmon. Счетчики общего количества байтов GC показывают, по крайней мере в моем приложении, что зарезервированные байты увеличиваются и уменьшаются в течение жизни моего приложения, например, около 30 МБ.

И, если ГХ работает в режиме сервера, возможно, .NET освобождает память чаще.

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