
У нас IIS запущен на двух серверах (IIS8 и 10), и в последнее время мы сталкиваемся с очень высоким использованием памяти нашими приложениями ASP.NET WebForms, доступ к которым осуществляется в основном через страницы aspx.
Происходит то, что со временем наши пулы приложений потребляют все больше и больше памяти, пока физическая память на сервере (64 ГБ) не будет почти исчерпана. Это определенно ненормально.
Мы пытались выяснить, почему это происходит, но у нас нет идей. Неясно, утечка ли это памяти в нашем приложении или нормальное поведение, так что, возможно, кто-то сможет пролить свет на это.
Факты:
Со временем пулы приложений резервируют и используют все больше памяти, которая не освобождается (диспетчер задач сообщает, что и рабочий набор, и размер фиксации очень велики, так что они фактически используются/удерживаются, верно?)
Профилировщики памяти, такие как ANTS, .dotMemory, .NET MemoryProfiler, говорят, что потребление управляемой памяти довольно низкое, около 20–200 МБ, и показывают большой объем неуправляемой памяти, которая будет использоваться, но свободна.
они не дают никаких указаний на то, что может быть причиной неуправляемого использования, даже при наличии снимков и методов подробного профилирования.
Если мы "нажмем" на стартовую страницу клавишей F5, не отпуская ее, мы можем увеличить потребление памяти до 2-5 гигабайт за минуту. Это немного безумно.
мы знаем, что пулы IIS/приложений имеют тенденцию резервировать память в зависимости от того, сколько памяти доступно, но это слишком много.
единственное, что мы видим, это то, что главная страница, похоже, хранится в памяти вместе со своими элементами управления и объектами ComponentModel, но нигде в профилировщиках памяти нет ни одной ссылки на какой-либо из наших объектов страницы или собственных классов пространства имен.
Год назад потребление памяти было нормальным и остановилось на отметке 2–3 гигабайта, но теперь мы не можем воспроизвести его со старой версией приложения.
то же самое происходит и на свежей локальной установке IIS под WIN10.
Приложение создано в режиме релиза, оптимизировано, на данный момент скомпилировано в одну DLL, также пробовалось без флага трассировки, размер 5 МБ
Похоже, нам нужно разобрать приложение, разделить его на несколько модулей и посмотреть, как они себя ведут. Сборки/библиотеки, загружаемые во время выполнения, могут, но не должны быть проблемой. На самом деле мы не так уж много ссылаемся (FreeTextBox, Microsoft ReportViewer, SharpCompress, Crystal Reports, AjaxControlToolKit 15), мы удалили все, кроме CrystalReports/AjaxControlToolKit, чтобы посмотреть, что произойдет, но ничего не изменилось.
Мы также используем множество элементов управления WebForms, включая таймеры и иногда UpdatePanels.
Мы также не знаем, как найти виновника с помощью профилировщиков памяти, предполагая, что существует скрытая ссылка, из-за которой одна или несколько страниц aspx удерживаются в памяти, поскольку экземпляры классов .NET никогда не показывают никаких ссылок на что-либо.
Мы будем рады получить ЛЮБУЮ подсказку относительно того, что мы неправильно понимаем относительно резервирования памяти или как устранить эту проблему с потреблением памяти.
Большое спасибо за ваше время!
EDIT (забыл упомянуть): - Мы добавили GC.Collect/WaitForPendingFinalizers/GC.Collect в нашу функцию Page_Load стартовой страницы, чтобы посмотреть, поможет ли это, и это действительно помогает на некоторое время или немного, пока не возникнет другая ситуация давления (с F5), когда использование памяти снова резко возрастет.
решение1
Когда GC.WaitForPendingFinalizers помогает, это может быть признаком использования памяти потоками. Если вы начинаете новый отдельный поток на page_load, он может использовать много памяти. Начните диагностику проблемы, проверив количество потоков в диспетчере задач.