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


8

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

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

プロセスリスト

アプリプール

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

ここに画像の説明を入力してください

メモリ制限の低い同じアプリプール。2、3分ごとにリサイクルイベントを引き起こす1000のリサイクルリクエストですが、ときどき実行されるだけです。

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


より良い結果が得られるかどうかを確認するには、メモリ制限ではなく時間制限を構成してみてください。こちらをご覧ください
ネイサンC

実際には100リクエスト後にリサイクルするように設定しましたが、うまくいくように見えますが、すべて同じですが、一部のアプリプール設定が期待どおりに機能しないようです。
lucuma 2014年

再利用のイベントログが有効になっていますか?何かありますか?
MichelZ、2014年

プライベートメモリの制限とリサイクルに関するエントリが2分ごとにあります。問題は、数日ごとにサーバーのメモリが爆発し、チェックするたびに、このアプリプールに(図に示すように)GBのRAMが使用されていることです。
lucuma 2014年

回答:


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年

私があなただったら、2つのしきい値があります。1つはリサイクル(低い方)、もう1つは殺害のしきい値です。アプリによっては、強制終了しただけではデータが失われる可能性があります。うまくいきました。
Nik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.