Назад | Перейти на главную страницу

Пул приложений не соблюдает ограничения памяти

Я имею дело с устаревшим приложением .NET с утечкой памяти. Чтобы попытаться смягчить ситуацию с нехваткой памяти, я установил пределы памяти пула приложений от 500 КБ до 500000 КБ (500 МБ), однако пул приложений, похоже, не соблюдает настройки, поскольку я могу войти в систему и просмотреть физический память для него (5 ГБ и выше независимо от того, какие значения). Это приложение убивает сервер, и я не могу определить, как настроить пул приложений. Какие настройки вы рекомендуете, чтобы этот пул приложений не превышал около 500 МБ памяти.

Вот пример, пул приложений использует 3,5 ГБ

Итак, сервер снова упал, и вот почему:

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

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

Я нашел этот пост, потому что изо всех сил пытаюсь ответить на похожий, где ограничения не ограничены. Видеть IIS WebLimits не соблюдается.

Однако я могу попытаться решить вашу проблему. Попробуйте приведенный ниже код C #. Вы можете сделать то же самое с PowerShell. Вам нужно будет запустить его с правами администратора.

 static void Main(string[] args)
    {

        string appPoolName = args[0];
        int memLimitMegs = Int32.Parse(args[1]);
        var regex = new System.Text.RegularExpressions.Regex(".*w3wp.exe \\-ap \"(.*?)\".*");

        //find w3wp procs....
        foreach (var p in Process.GetProcessesByName("w3wp"))
        {

            string thisAppPoolName = null;

            try
            {
                //Have to use WMI objects to get the command line params...
                using (var searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + p.Id))
                {
                    StringBuilder commandLine = new StringBuilder();
                    foreach (ManagementObject @object in searcher.Get())
                    {
                        commandLine.Append(@object["CommandLine"] + " ");
                    }

                    //extract the app pool name from those.
                    var r = regex.Match(commandLine.ToString());
                    if (r.Success)
                    {
                        thisAppPoolName = r.Groups[1].Value;
                    }

                    if (thisAppPoolName == appPoolName)
                    {
                        //Found the one we're looking for. 
                        if (p.PrivateMemorySize64 > memLimitMegs*1024*1024)
                        {

                            //it exceeds limit, recycle it using appcmd. 

                            Process.Start(Path.Combine(System.Environment.SystemDirectory , "inetsrv", "appcmd.exe"), "recycle apppool /apppool.name:" + appPoolName);

                            Console.WriteLine("Recycled:" + appPoolName);
                        }
                    }
                }
            }
            catch (Win32Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }