webentwicklung-frage-antwort-db.com.de

Speicherleck finden

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. ANTS only 300 MB

IIS-Prozess dauert 1 GB  [1]: https://i.stack.imgur.com/Ig8 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.)  422MB after release  IIS 1.2GB  Summary  4MB of strings

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

Aktualisieren

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:

 enter image description here

Update 2

Ich habe DebugDiag ausgeführt und die Site im Stresstest getestet, bis sie ungefähr 3,5 GB RAM verbraucht hat.

 enter image description here

Und Chakra ist eine Microsoft-Bibliothek.

 enter image description here  enter image description here

Also jetzt habe ich 2 Fragen.

  1. Ist es der ChakraCore, der ein Leck hat, oder ist es derjenige, der es verwendet/zuordnet? Wie definiere ich welche Bibliothek?

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).

6
Ashkan Sirous

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

  1. Verwenden von DebugDiag (Aufzeichnen aufeinanderfolgender Hang-Dumps)
    • Starten Sie DebugDiag Collection und wechseln Sie zur Registerkarte Prozesse  debugdiag process tab
    • Starten Sie Ihren Stresstest
    • Überprüfen Sie die Speichernutzung und erfassen Sie einen Hang-Dump , sobald die Speicherkapazität 1 GB erreicht hat.
      • klicken Sie mit der rechten Maustaste auf den Prozess w3wp.exe
      • wählen Sie die Option Create Full Memory Dump  capture full memory hang dump
    • Erfassen Sie einen weiteren Speicherauszug mit 2 GB und einen mit 3,5 GB
    • Sie sollten Speicherauszüge im Ordner C:\ProgramFiles\DebugDiag\Logs\Misc\speichern.
    • Klicken Sie mit der rechten Maustaste auf die Speicherauszugsdatei und wählen Sie die Option .NET-Speicherproblem analysieren  Analyse .net memory issue

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

  1. ** Fehler oder Warnungen ** - Achten Sie genau auf Warnungen oder Fehler, die von der Debugdiag-Analyse oben im Bericht angezeigt werden.
  2. .NET GC-Heap-Informationen - Gesamte Commit-Größe - Dies entspricht in etwa Ihrer .net-Speicherauslastung.
  3. 40 speicherintensivste .NET-Objekttypen - Dies kann verwendet werden, um die Speichererhöhung in aufeinanderfolgenden Dumps zu vergleichen. Hier erfahren Sie, welche Objekte zu Problemen führen. Manchmal kommen einige Objekte, die Sie überhaupt nicht verwenden, und möglicherweise aus einer Drittanbieter-Bibliothek. Oder Sie sehen Objekte, die Sie selbst erstellt haben
  4. Top-Objekte in der Finalizer-Warteschlange - Dies gibt Ihnen einen Hinweis darauf, ob Ihr Finalizer blockiert ist .Objects.Some ähnliche Probleme werden diskutiert hier und hier
  5. Objekte auf dem Heap für große Objekte - Dies führt zu einer Speicherfragmentierung und einem Heap für große Objekte, die Objekte mit einer Größe von mehr als 85 KB enthalten.
  6. Größe von Cache, Datentabellen, Anwendungsdomänen, dynamischen Assemblys usw. . Es ist keine gute Idee, eine große Anzahl von Anwendungsdomänen in einem Prozess zu haben

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!

4
Rohith

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).

1
youen

Wenn es darum geht, Speicherlecks zu beheben, gibt es zwei Schritte.

  1. Ermitteln, wo sich der Speicherverlust befindet.
  2. Speicherleck beheben.

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.

 enter image description here

Folgen Sie dann den folgenden Schritten.

  1. Erstellen Sie einen Basis-Snapshot, bevor Sie Vorgänge ausführen.
  2. Führen Sie die Operationen aus, bei denen Sie vermuten, dass sie Speicherlecks aufweisen.
  3. Machen Sie noch ein paar Schnappschüsse, bis Sie einen recht stabilen Schnappschuss erhalten.
  4. Vergleichen Sie den letzten Schnappschuss mit der Basis und sehen Sie, welche Instanzen wachsen.
1
CharithJ

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.

https://channel9.msdn.com/Series/PerfView-Tutorial/Tutorial-10-Investing-NET-Heap-Memory-Leaks-Part1-Collecting-the-data

https://channel9.msdn.com/Series/PerfView-Tutorial/Tutorial-11-Investing-NET-Heap-Memory-Leaks-Part2-Analyzing-the-data

0
Amit