Der App-Pool beachtet keine Speicherbeschränkungen

8

Ich habe es mit einer älteren .NET-App zu tun, die einen Speicherverlust aufweist. Um zu versuchen, eine Auslaufspeichersituation zu verringern, habe ich die Speicherbeschränkungen für den App-Pool zwischen 500 KB und 500000 KB (500 MB) festgelegt. Der App-Pool scheint jedoch die Einstellungen nicht zu berücksichtigen, da ich mich anmelden und den physischen anzeigen kann Speicher dafür (5 GB und mehr, egal welche Werte). Diese App beendet den Server und ich kann anscheinend nicht feststellen, wie der App-Pool angepasst werden soll. Welche Einstellungen empfehlen Sie, um sicherzustellen, dass dieser App-Pool nicht mehr als 500 MB Arbeitsspeicher umfasst?

Hier ist ein Beispiel, der App-Pool verwendet 3,5 GB

Prozessliste

App-Pool

Der Server ist gerade wieder abgestürzt, und hier ist der Grund:

Geben Sie hier die Bildbeschreibung ein

Derselbe App-Pool mit niedrigen Speicherbeschränkungen, eine 1000-Recycling-Anforderung, die alle zwei oder drei Minuten ein Recycling-Ereignis verursacht, aber manchmal einfach wegläuft.

Ich bin auch offen für jedes Tool, das diesen Prozess überwachen kann (entweder alle 30 Sekunden als Aufgabe oder als Dienst ausführen) und ihn beenden kann, wenn er ein bestimmtes Limit überschreitet.

lucuma
quelle
Versuchen Sie, ein Zeitlimit anstelle eines Speicherlimits zu konfigurieren, um festzustellen, ob Sie bessere Ergebnisse erzielen. Sehen Sie das .
Nathan C
Ich habe es tatsächlich so eingestellt, dass es nach 100 Anfragen wiederverwendet wird, was anscheinend besser funktioniert, aber es scheint, als ob einige der Einstellungen für den App-Pool nicht wie erwartet funktionieren.
Lucuma
Haben Sie Eventlogging für das Recyling aktiviert? irgendetwas da drin?
MichelZ
Alle 2 Minuten wird ein Eintrag zum privaten Speicherlimit und zum Recycling erstellt. Das Problem ist, dass alle paar Tage der Speicher des Servers explodiert und jedes Mal, wenn ich nachschaue, in diesem App-Pool (wie die Grafik zeigt) GB RAM verwendet werden.
Lucuma

Antworten:

2

Ich habe diesen Beitrag gefunden, weil ich Schwierigkeiten habe, einen ähnlichen Beitrag zu beantworten, bei dem die Grenzwerte nicht eingeschränkt werden. Siehe IIS WebLimits werden nicht beachtet .

Ich kann jedoch auf Ihr Problem eingehen. Probieren Sie den folgenden C # -Code aus. Sie könnten das gleiche mit Powershell tun. Sie müssen es mit Administratorrechten ausführen.

 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());
            }
        }
    }
Nik
quelle
Ich werde das morgen ausprobieren und sehen, was passiert.
Lucuma
Ich habe das Skript ausprobiert und es findet den Prozess nicht.
lucuma
Und Sie führen es mit vollen Administratorrechten aus? Können Sie w3wp im Task-Manager für Ihren App-Pool sehen?
Nik
Ja, das habe ich herausgefunden, nachdem ich den Kommentar gepostet habe. Ich habe das Skript so geändert, dass der Prozess abgebrochen wird, anstatt den App-Pool zu recyceln, da der Recycling bombardiert wird, wenn der Speicherverlust den gesamten Speicher belegt. Theoretisch sollte es funktionieren, wenn das Leck durcheinander gerät (in der Hoffnung).
Lucuma
Wenn ich Sie wäre, hätte ich zwei Schwellenwerte, einen für das Recycling (niedriger) und einen für das Töten. Abhängig von Ihrer App können Sie im Flug Daten verlieren, wenn Sie nur töten. Ich bin froh, dass es geklappt hat.
Nik