Мы запускаем некоторые веб-серверы X64 Win Server 2012 (так IIS 8).
Мы замечаем, что свободная память на ящиках постоянно находится на уровне 5-10%. На самом деле мы запускаем на этих компьютерах довольно много приложений (13 сайтов, 80 приложений, более 13 пулов приложений). Большая часть кода дублируется для каждого сайта, поскольку они соответствуют разным базам данных и физическим сайтам, но приложение остается тем же.
Мы вполне уверены, что у нас есть утечка памяти в приложении, поскольку память продолжает расти, поэтому мы сразу же смотрим на это, но меня смущает распределение памяти и управление IIS. Мне интересно, отличается ли это для серверов IIS 8 или x64 (недавно мы только что перешли на x64).
Таким образом, в основном каждый из наших веб-серверов имел 6 ГБ памяти и имел 5-10% свободной памяти. Самое популярное приложение, в котором, как мы уверены, происходит утечка, использовало колоссальные 1,2 ГБ памяти. Следующим было около 800 МБ, а остальные в среднем составляли около 400-500 МБ (все эти значения являются частной памятью, как видно в диспетчере задач) .Как я уже сказал, код дублирован, поэтому, если есть утечка на одном сайте, она будет во всех их, просто в разных физических местах могут быть включены или отключены некоторые функции, что объясняет большое несоответствие.
Пока мы работаем над проблемой, мы решили просто увеличить объем памяти, чтобы не столкнуться с проблемами. Итак, вчера вечером я отключил каждый сервер и удвоил объем памяти до 12 ГБ. Сегодня утром 3 сервера используют 77%, 80% и 82% используемой памяти. Все процессы увеличили использование памяти в 1,5-2 раза.
Так что теперь я в замешательстве. Это действительно утечка памяти? Или есть какое-то предварительное выделение памяти? Или он никогда не освобождает память, если другой процесс не запрашивает ее как SQL Server, или как?
Что сдерживало уровни памяти на уровне 6 ГБ, если они вдруг стали такими огромными, когда объем памяти удвоился? Установлены ли пороги? IIS / ASP просто не собирает мусор, пока не кончится память или что?
Любые ответы приветствуются.
Конфигурация кэширования вывода по умолчанию в IIS включает кэширование как в режиме ядра, так и в пользовательском режиме.
Кэширование в режиме ядра управляется собственным драйвером HTTP (также известным как http.sys) и выполняется молниеносно, но может обслуживать только «общедоступный» контент, поскольку он должен иметь возможность реагировать на попадание в кеш до того, как запрос достигнет веб приложение.
К сожалению, это означает, что некоторые типы запросов не могут быть кэшированы в режиме ядра, включая авторизованные сеансы (например, посещения веб-сайтов, требующих аутентификации).
Тип настройки, который вы описываете, звучит как своего рода клиентская служба с несколькими арендаторами, что наводит меня на мысль, что кэширование в режиме ядра не имеет значения.
С другой стороны, кэширование в пользовательском режиме управляется на уровне приложения, а кэшированные объекты хранятся в наборе памяти обслуживающего рабочего процесса. Общий размер кеша регулируется атрибутом, называемым maxCacheSize
на system.webServer/Caching
элемент конфигурации.
По умолчанию maxCacheSize
атрибут установлен на 0
что примерно переводится как Позвольте IIS выделить столько памяти, сколько допустимо на данный момент.
Если у вас много последовательных небольших (<256 КБ) попаданий, но мало коэффициент попадания в кеш URI, IIS наверняка съест всю предоставленную вами память.
Вы можете легко проверить, правда это или нет, понизив maxCacheSize
значение или полное отключение кеширования вывода на сервере.
Если вы все еще уверены, что у вас проблема с памятью в вашем приложении, запустите Performance Monitor и взгляните на объект счетчика производительности «Приложения ASP.NET».
Выберите счетчики GC и посмотрите, как разгоняется сборка мусора.
Коллекции Gen0 должны представлять почти все удаления, тогда как большое количество коллекций Gen1 и Gen2 может указывать на проблему с более длительным, чем необходимо, сроком службы объектов, что является распространенным признаком сбоя управления памятью.