Ich habe eine Webanwendung, die ich mit vielen verschiedenen Komponenten von Drittanbietern, einem CMS und natürlich meinem Code geschrieben habe. Aus irgendeinem Grund habe ich eine Speicherausnahme.
Skript hat eine Ausnahme ausgelöst: Nicht genügend Speicher
Ich habe versucht herauszufinden, was los ist. Folgendes habe ich gefunden:
Ich habe den Test mit 50 Threads durchgeführt, um 15 Seiten meiner Webanwendung aufzurufen. Das Gedächtnis scheint in Ordnung zu sein. Der Prozess IIS belegt nur 400 MB RAM
Ich habe ein Leerzeichen in web.config hinzugefügt und plötzlich begann mein IIS -Prozess innerhalb von 30 Minuten auf mehr als ein GB zu wachsen. Visual Studio konnte keinen Schnappschuss meines Speichers machen, da dieser zu groß ist (wirklich ?!) Also habe ich ANTS Memory Profiler installiert, aber es heißt, dass meine Anwendung nur ungefähr 300 MB verwendet.
IIS-Prozess dauert 1 GB pY.png
Ich habe den Test nach einigen Minuten abgebrochen, aber der Speicher wurde nicht freigegeben.
(ANTS-Profiler funktioniert nicht mehr, daher habe ich ihn neu gestartet.)
Es sieht nicht so aus, als ob die Anwendung 100-200 MB Arbeitsspeicher verwendet, speziell wenn ich Output-Caching für meine Controller verwende. Was ich nicht verstehe, ist, warum der von IIS verbrauchte Speicher ständig wächst und was falsch ist
Meine Anwendung wurde automatisch mit einem Absturz in W3WP neu gestartet, wodurch IIS den Speicher freigab, während mein Stress eine Weile lang nicht lief:
Anwendung: w3wp.exe Framework Version: v4.0.30319 Beschreibung: Der Vorgang wurde aufgrund eines internen Fehlers in der .NET Runtime bei IP 5A3A86F1 (5A0F0000) mit Exit-Code 80131506 abgebrochen.
und
Fehlerhafter Anwendungsname: w3wp.exe, Version: 10.0.15063.0, Zeitstempel: 0xacce422f Fehlerhafter Modulname: clr.dll, Version: 4.7.2098.0, Zeitstempel: 0x59028d36 Ausnahmecode: 0xc0000005 Fehleroffset: 0x002b86f1 Fehlerhafte Prozess-ID: 0x50a4 Anwendungsstartzeit: 0x01d2ee688f323893 Fehlerhafter Anwendungspfad: C:\WINDOWS\SysWOW64\inetsrv\w3wp.exe Fehlerhafter Modulpfad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll Berichts-ID: 4362ddc5-f8d7- 4441-8916-3830f9268b3a Vollständiger Name des fehlerhaften Pakets: Fehlerhafte paketbezogene Anwendungs-ID:
Ich habe DebugDiag ausgeführt und die Site im Stresstest getestet, bis sie ungefähr 3,5 GB RAM verbraucht hat.
Und Chakra ist eine Microsoft-Bibliothek.
Also jetzt habe ich 2 Fragen.
2- Es heißt 27.000 Zuweisungen. Bedeutet das, dass sich noch 27.000 im Speicher befinden oder einige davon zugewiesen und dann entsorgt werden könnten?
3- Es sagt mir immer noch nichts über den Rest von 3 GB verbrauchtem RAM. Insgesamt sind es nur 600 MB (privat + virtuell).
In Ihrer Analyse stelle ich fest, dass die .net-Analyse nicht korrekt durchgeführt wurde. Führen Sie die Analyse auf demselben Computer durch, auf dem Sie den Speicherauszug erfasst haben?
Damit debugdiag ordnungsgemäß funktioniert, muss auf dem Analysegerät dieselbe Version des .net-Frameworks (der Anwendung) installiert sein.
Bitte führen Sie keinen systemeigenen Speicher-Leak-Dump wie this durch, es sei denn, es wurde kein nicht verwaltetes Leck ermittelt. Aus Ihrer Analyse geht hervor, dass dies ein verwaltetes Leck ist.
Wenn Sie die Datei web.config geändert haben, wird eine Anwendungsdomäne entladen und neu geladen
Lassen Sie uns Schritt für Schritt tun
Vergleichen Sie nun die Analyse der einzelnen Speicherauszugsdateien (1 GB, 2 GB, 3,5 GB). Sie sollten feststellen, welche .NET-Objekte zunehmen und keinen Müll sammeln.
In der Speicheranalyse sollten Sie CLR-Informationen **** ,. NET GC-Heap-Informationen , Den meisten Speicher verbrauchen .NET-Objekte etc wie unten. Dies wird eintreten, wenn Ihre .net-Symbole durch die Debugdiag-Analyse korrekt identifiziert werden
CLR Information
CLR version = 4.6.1648.0
Microsoft.Diagnostics.Runtime version = 0.9.2.0
.NET GC Heap Information
Number of GC Heaps: 4
Heap Size 0x4001ce8 (67,116,264)
Heap Size 0x3d5cca0 (64,343,200)
Heap Size 0x3f8b0d0 (66,629,840)
Heap Size 0x3ccb0d0 (63,746,256)
GC Heap Size 249.71 MBytes
Total Commit Size 249 MB
Total Reserved Size 17158 MB
40 most memory consuming .NET object types
System.Char[] 193.01 MBytes (12450 objects )
Free 45.21 MBytes (4760 objects )
System.String 1.56 MBytes (18072 objects )
==============trimmed out =======================
DebugDaig Eine automatisierte Analyse sollte Folgendes ergeben
Bitte beachten Sie, dass die automatische Debugdiag-Analyse manchmal die Ursache nicht ermitteln kann und eine manuelle Analyse mit windbg erfordert. DebugDiag-Analyse finden Sie in diesem Video .
Hoffe das hilft!
Da es so aussieht, als könnten Sie Ihr Problem reproduzieren, ist es manchmal am einfachsten, Dinge zu entfernen, von denen Sie glauben, dass sie die Ursache sind, und es erneut zu testen (es sei denn, Sie benötigen viel Zeit, um zu sehen, ob es stark wächst oder nicht?).
Irgendwann hört der Fehler auf und Sie wissen, welcher Code dafür verantwortlich war.
Abhängig von Ihrer Codebasis ist es jedoch nicht immer einfach, Code zu entfernen und dennoch etwas zu testen (d. H. Ohne die Anwendung zum Absturz zu bringen).
Wenn es darum geht, Speicherlecks zu beheben, gibt es zwei Schritte.
Normalerweise ist der erste Schritt schwierig. Daher würde ich empfehlen, mit dem ANTS-Speicherprofiler fortzufahren und zuerst welche genauen Instanzen wachsen zu suchen.
Profilerstellung einer ASP.NET-Anwendung auf IIS
In Ihrer Frage haben Sie das Klassenlistenergebnis angezeigt, das auch Klassen mit Systemnamespace enthält. Um das Rauschen zu beseitigen, können Sie die Option "Nur Klassen mit Quelle anzeigen" auswählen.
Folgen Sie dann den folgenden Schritten.
Sie erwähnten "Ich habe ein Leerzeichen in web.config hinzugefügt und plötzlich begann mein IIS -Prozess innerhalb von 30 Minuten auf mehr als ein GB zu wachsen". In welchem web.config-Tag haben Sie dieses Leerzeichen angehängt. Welcher Teil Ihres Codes verwendet ihn? Ist dieser Teil Ihres Codes nicht in der Lage, eine Ausnahme zu behandeln, ohne einen Speicherverlust zu verursachen? Verwenden Sie PerfView (Dump GC-Heap), um den Dump zu analysieren. Dies kann genau sagen, welches Objekt so viel Speicherplatz einnimmt. In älteren Versionen von .net handelt es sich um Objekte auf großen Objekthaufen (große Arrays) oder offene und falsch behandelte Datenbankverbindungen und -dateien.