Почему наши пулы приложений IIS 6 занимают в десять раз больше памяти, используемой CLR
Наши пулы приложений IIS 6.0 занимают при первой загрузке страницы 155 МБ памяти. При последующем обновлении той же страницы объем используемой памяти пула приложений увеличивается примерно до 245 МБ.
Это веб-приложение и использует элементы управления Entity Framework и DevExpress.
Сначала я думал, что это утечка памяти, но при дальнейшем исследовании с использованием профилировщика памяти обнаружил, что более половины пространства, занимаемого пулом приложений, было свободным, но фрагментированным.
Это указало пальцем на фрагментацию памяти кучи больших объектов как на преступника. Был действительно длинный список размером около 980 КБ, который, как правило, может вызывать фрагментацию, особенно когда список увеличивается и изменяет размеры, оставляя дыры в памяти.
Итак, я создал составной список, в основном список списков, идея в том, что, поскольку каждый список будет меньше 85000 байт, он будет размещен в обычной куче, которая уплотняется после сборки мусора (в отличие от кучи больших объектов, которая никогда не уплотняется)
Он ожидал, что составной список сделает то же самое, что и в других местах, где другие использовали списки списков, чтобы гарантировать, что объекты избегают кучи больших объектов, однако в этом случае, похоже, не было никакой реальной разницы, и память пула приложений все еще около 240 МБ, тогда как профилировщики памяти сообщают о CLR-памяти dot net около 10 МБ.
Я планирую сделать дамп памяти, чтобы увидеть, что происходит, но просто подумал, есть ли у кого-то еще мнение о возможных причинах.
1 ответ
Я был бы готов поспорить на значительную сумму денег, что вы видите гигантские строки, занимающие блоки в куче больших объектов - это особенно верно для любой схемы частичного рендеринга - которая будет содержать вывод html, который должен быть доставлено в браузер.
Я уже сталкивался с этой проблемой раньше, но решение было болезненным - в основном мне пришлось пройти и создать путь "потоковой записи" вместо стандартного подхода "агрегировать все выходные данные html элементов управления / представлений вместе", который (или, по крайней мере, был) по умолчанию метод MVC, WebForms и т. д.
Удачи! Если вы хотите пойти по этому пути, вы бы хотели создать набор расширений рендеринга, которые открывают Response
поток и напрямую писать в них, как содержание рассчитывается.