wake-up-neo.com

Wie verwende ich eine Speicherauszugsdatei, um einen Speicherverlust zu diagnostizieren?

Ich habe einen .NET-Dienst mit einem normalen privaten Arbeitssatz von ca. 80 MB. Während eines kürzlich durchgeführten Auslastungstests wurde eine Speicherauslastung von 3,5 GB erreicht, was dazu führte, dass auf dem gesamten Computer nur noch wenig physischer Speicher verfügbar war (3,9 von 4 GB). Der Speicher wurde nicht lange nach dem Beenden des Auslastungstests freigegeben. Mit dem Task-Manager habe ich eine Sicherungsdatei des Prozesses erstellt und in Visual Studio 2010 SP1 geöffnet, und ich kann mit dem Debuggen beginnen.

Wie diagnostiziere ich das Speicherproblem? Ich habe dotTrace Memory 3.x zur Verfügung. Unterstützt es die Erstellung von Speicherprofilen für Dump-Dateien? Wenn nicht, helfen die Speicherprofilfunktionen von Visual Studio 2010 Premium (derzeit habe ich Professional)? Kann WinDbg helfen?

UPDATE: Das neue Visual Studio 2013 Ultimate kann jetzt Speicherprobleme nativ mithilfe von Speicherauszugsdateien diagnostizieren. Siehe dieser Blog-Beitrag für weitere Details.

68
Allon Guralnek

Installieren Sie WinDbg. Sie müssen sicherstellen, dass Sie je nach Speicherauszug die richtige Version x86 oder x64 erhalten. Hier ist ein direkter Link zum Download für x86.

Dazu müssen Sie sicherstellen, dass Sie den richtigen Speicherauszug erstellt haben. Mit dem Task-Manager können Sie die Dump-Datei erstellen (Rechtsklick auf Prozess -> Dump-Datei erstellen). Wenn Sie 64-Bit verwenden und Ihr Prozess x86 ist, verwenden Sie die 32-Bit-Version des Task-Managers (C:\Windows\SysWOW64\taskmgr.exe), um die Speicherauszugsdatei zu erstellen. Siehe mein Artikel für weitere Informationen zum Erstellen von Dump-Dateien, zB wenn Sie XP und windbg zum Erstellen der Dump-Datei benötigen.

Warnung Es gibt eine ziemlich steile Lernkurve und die Dinge funktionieren möglicherweise nicht genau wie hier beschrieben.

Ich gehe davon aus, dass Sie .NET4 verwenden, vorausgesetzt, Sie können den Dump in Visual Studio öffnen. Hier ist eine very Kurzanleitung, die Ihnen bei der Arbeit mit Ihrer dmp-Datei hilft:

1) Führen Sie WinDbg aus und setzen Sie den Symbolpfad (Datei -> Symbolsuchpfad) auf

SRV*c:\symbols*http://msdl.Microsoft.com/download/symbols

2) Öffnen Sie Crash Dump oder ziehen Sie Ihre .DMP-Datei auf WinDbg.

3) Geben Sie dies in das Befehlsfenster ein

.loadby sos clr

(Zu Ihrer Information, für .NET 2 sollte der Befehl .loadby sos mscorwks)

4) dann tippe dies ein

!dumpheap -stat

hier werden die Objekttypen und deren Anzahl aufgelistet. sieht ungefähr so ​​aus:

enter image description here

Sie müssen dies im Kontext Ihrer Anwendung analysieren und feststellen, ob etwas ungewöhnlich erscheint.

Es gibt viel mehr zu windbg, Google ist dein Freund.

122
wal

Im Allgemeinen bedeutet ein Leck in einer verwalteten Anwendung, dass etwas nicht erfasst wird. Übliche Quellen sind

  • Ereignishandler: Wenn der Abonnent nicht entfernt wird, behält der Herausgeber ihn bei.

  • Statik

  • Finalizer: Ein blockierter Finalizer verhindert, dass der Finalizer-Thread andere Finalizer ausführt und dass diese Instanzen gesammelt werden.

  • In ähnlicher Weise hält ein festgefahrener Thread die darin enthaltenen Wurzeln fest. Natürlich, wenn Sie festgefahrene Threads haben, die sich wahrscheinlich auf mehrere Ebenen auf die Anwendung auswirken.

Um dies zu beheben, müssen Sie den verwalteten Heap überprüfen. Mit WinDbg + SOS (oder PSSCOR)) können Sie dies tun. Der Befehl !dumpheap -stat Listet den gesamten verwalteten Heap auf.

Sie müssen eine Vorstellung von der Anzahl der Instanzen jedes Typs haben, die auf dem Heap zu erwarten sind. Wenn Sie etwas Ungewöhnliches gefunden haben, können Sie mit dem Befehl !dumpheap -mt <METHOD TABLE> Alle Instanzen eines bestimmten Typs auflisten.

Der nächste Schritt besteht darin, die Wurzel dieser Instanzen zu analysieren. Wählen Sie eine zufällig und machen Sie einen !gcroot Darauf. Das wird zeigen, wie diese bestimmte Instanz verwurzelt ist. Suchen Sie nach Ereignishandlern und angehefteten Objekten (die normalerweise statische Referenzen darstellen). Wenn Sie die Finalizer-Warteschlange dort sehen, müssen Sie überprüfen, was der Finalizer-Thread tut. Verwenden Sie dazu die Befehle !threads Und !clrstack.

Wenn für diese Instanz alles in Ordnung ist, wechseln Sie zu einer anderen Instanz. Wenn das nichts ergibt, müssen Sie möglicherweise zurückgehen, um den Haufen erneut zu betrachten und von dort aus zu wiederholen.

Andere Ursachen für Undichtigkeiten sind: Nicht entladene Assemblys und Fragmentierung des Large Object Heap. SOS/PSSCOR kann Ihnen auch dabei helfen, diese zu finden, aber ich werde die Details für den Moment überspringen.

Wenn Sie mehr wissen möchten, empfehle ich Tess 'Blog . Ich habe auch ein paar Videos über die Verwendung von WinDbg + SOS ( hier und hier ) gemacht.

Wenn Sie die Möglichkeit haben, den Prozess während der Ausführung zu debuggen, empfehle ich die Verwendung von PSSCOR anstelle von SOS. PSSCOR ist im Wesentlichen ein privater Zweig der SOS= - Quellen, der mit zusätzlichen Befehlen erweitert wurde, und viele der vorhandenen SOS - Befehle wurden ebenfalls verbessert Die PSSCOR-Version des Befehls !dumpheap Enthält eine sehr nützliche Delta-Spalte, die die Fehlerbehebung bei Speicherverlusten erheblich vereinfacht.

Um es zu benutzen, müssen Sie Ihren Prozess starten, WinDbg anhängen und PSSCOR laden und einen !dumpheap -stat Ausführen. Anschließend lassen Sie den Prozess erneut ausführen, damit Zuordnungen vorgenommen werden. Unterbrechen Sie die Ausführung und wiederholen Sie den Befehl. PSSCOR zeigt Ihnen nun die Anzahl der Instanzen an, die seit der vorherigen Überprüfung hinzugefügt/entfernt wurden.

29
Brian Rasmussen

Seit Version 2017.2 unterstützt JetBrains dotMemory die Speicherauszugsanalyse von Windows mit all seiner Leistung und ausgefallenen GUI.

4
Ed.ward

http://msdn.Microsoft.com/en-us/library/ee817660.aspx

Microsoft hat hier eine Anleitung. Für Anfänger ist es jedoch zu schwierig.

dotTrace kann visuelle Speicherdiagramme generieren (besser als WinDbg), aber niemals für Dumps verwenden.

0
Lex Li