应用程序池不遵守内存限制


8

我正在处理有内存泄漏的旧版.NET应用程序。为了尝试缓解内存失控的情况,我将应用程序池的内存限制设置为500KB至500000KB(500MB)之间的任意值,但是由于我可以登录并查看物理内存,因此应用程序池似乎不遵守设置内存(无论什么值,5GB及以上)。该应用正在杀死服务器,我似乎无法确定如何调整应用池。为了确保此应用程序池不超过500mb的内存,建议您建议什么设置。

这是一个示例,应用程序池使用的是3.5GB

工艺清单

应用程序池

因此,服务器再次崩溃,这就是原因:

在此处输入图片说明

具有低内存限制的同一个应用程序池,有1000个回收请求,每隔两到三分钟就会导致一次回收事件,但有时它会消失。

我也可以使用任何可以监视此过程的工具(作为任务或服务每30秒运行一次),并在超过一定限制时将其杀死。


尝试配置时间限制而不是内存限制,以查看是否获得更好的结果。看到这个
内森·C

实际上,我将其设置为在100个请求之后可以回收,这似乎效果更好,但是所有这些似乎都像我期望的那样在某些应用程序池设置中不起作用。
lucuma

您是否启用了事件日志记录功能?里面有东西吗?
MichelZ 2014年

每2分钟就会有一个有关私有内存限制和回收的条目。问题是服务器的内存每隔几天就会耗尽,并且每次我检查时,此应用程序池都有(如图所示)使用的Gb的ram。
lucuma 2014年

Answers:


2

我找到这篇文章是因为我正在努力回答不受限制的类似文章。请参阅不遵守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());
            }
        }
    }

明天我会尝试一下,看看会发生什么。
lucuma 2014年

我尝试了脚本,但找不到进程。
lucuma 2014年

并且您正在以完全管理员权限运行它?您可以在任务管理器中为您的应用程序池看到w3wp吗?
Nik

是的,我在发表评论后就知道了。我修改了脚本以杀死进程,而不是回收应用程序池,因为如果内存泄漏消耗了所有内存,回收站将爆炸。从理论上讲,当泄漏成为麻烦时,它应该起作用。
lucuma 2014年

如果我是你,那么我将有两个门槛,一个是回收(降低)门槛,另一个是杀死门槛。如果您只是杀死,则可能会丢失飞行中的数据,具体取决于您的应用程序。很高兴它解决了。
尼克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.