Ответы с форумов MSDN

Очистка памяти в пуле приложений ASP.NET

Date: 21.01.2020 8:32:42

>Меня уверяют, что очистка пула возможна лишь через рестарт пула приложений

Технически это не так. Пул приложений - обычный процесс .NET Framework. Когда ему нужна память, он выделяет ее, но когда память больше не нужна, он сразу ее не освобождает. Лишь когда в системе мало свободной памяти (или при кое-каких других условиях), запустится сборка мусора и ненужная память будет освобождена. Т.е. очистка памяти, конечно, возможна не только при рестарте, но вам от этого толку мало, так как вручную вы сделать эту очистку все равно не можете. Судя по вашем предыдущим 2 темам, реальная проблема в том, что на пул приложений IIS + ваши приложения ASP.NET Core (при OutOfProcess model) хостинг позволяет использовать всего 1GB?

Я думаю ответ тут можно дать только один: в таких условиях вы не сможете заставить надежно работать приложение ASP.NET Core. Любая система с GC, по дизайну, жрет память в тех пределах, которые ей внешняя среда позволяет сожрать. При существовании дополнительного искусственного ограничения, о котором эта система не знает, она не сможет устойчиво функционировать. Хостинг просто прибьет ваши процессы до того, как они будут иметь шанс на сборку мусора. Рабочий способ ограничения доступной памяти в .NET Core - запуск (без IIS) в Docker контейнере с ограничением по памяти. CoreCLR умеет считывать это ограничение и не выделять памяти больше, чем нужно. В ваших условиях ответ - никак.

Message 139

Date: 23.01.2020 6:59:43

"Реально шансы что это правда и GC якобы никогда не запускается если объем используемой памяти менее 1 ГБ практически нулевые. Я бы сказал что это нонсенс, вот и все. Если бы это было так, то программ на CLR с объемом памяти менее 1 ГБ просто бы не было и я знаю что это не так. "

Тут тонкая разница между Workstation и Server GC. Для Workstation действительно, первый запуск GC уже при 20МБ выделенной памяти. А вот для серверного, по моим тестам, первый GC запускается только когда память заходит за 1GB. 

Message 138

Date: 23.01.2020 18:27:57

"Вызывала GC.AddMemoryPressure(long.MaxValue); и GC.RemoveMemoryPressure(long.MaxValue); но эффекта для пула не было. Или там должен быть определенный танец с бубнами?"

Тут точно только шамана с бубном вызывать... Как GC.AddMemoryPressure тут поможет? Тем более если вызывать с таким большим значением - его CLR скорее всего просто отметет как некорректное. Увеличение бюджета неуправляемой памяти разве что поможет поскорее вызвать сборку мусора в своем процессе, но никак не в другом. На него это никак не повлияет.

Message 137

Date: 24.01.2020 4:45:35

"Скорее всего никак не поможет так как в не думаю что утверждение о неком пороге GC верно. Документация таких порогов не устанавливает, а лишь говорит о том что порог динамически меняется. Что имеет смысл, так как для программ которые использует 10 МБ и 10 ГБ они будут очень разными."

Ну да, по сути речь не о каком-то жестком пороге, а о том, что для Server GC сборка мусора запускается значительно реже, чем для Workstation GC. Точнее, речь не о сборке мусора как таковой, а о сжатии кучи, которое потенциально отдает освобожденную память ОС. Обычная сборка, которая просто помечает участки памяти неиспользуемыми, конечно, запускается также часто и для серверного GC, но она не отдает память в ОС, и поэтому из внешнего мира незаметна. Реальный порог, когда в процессе запустится первое сжатие кучи, зависит от многих факторов. "Порог в 1 Гб" - это как гипотеза плоской Земли, работает в неких узких рамках, но в более широкой перспективе неверно. 


Автор: VadimTagil

Главная страница - Список тем - Репозиторий на GitHub