web-dev-qa-db-ja.com

アプリプールはメモリ制限を尊重しません

メモリリークのあるレガシー.NETアプリを扱っています。暴走メモリの状況を試して緩和するために、アプリプールのメモリ制限を500KBから500000KB(500MB)のいずれかに設定しましたが、ログインして物理的に表示できるため、アプリプールは設定を尊重していないようですそのためのメモリ(値に関係なく5GB以上)。このアプリはサーバーを強制終了しており、アプリプールを調整する方法を判断できません。このアプリプールが約500 MBのメモリを超えないようにするために、どの設定を推奨しますか。

以下は例です。アプリプールは3.5GBを使用しています

Process List

App pool

つまり、サーバーが再びクラッシュしました。その理由は次のとおりです。

enter image description here

同じアプリプールでメモリ制限が低く、2、3分ごとにリサイクルイベントが発生する1000のリサイクルリクエスト。

また、このプロセスを監視でき(タスクまたはサービスとして30秒ごとに実行)、制限を超えた場合は強制終了できるツールを利用できます。

8
lucuma

私がこの投稿を見つけたのは、制限が制限されていない同様の記事に答えるのに苦労しているためです。 尊重されていない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());
            }
        }
    }
2
Nik