Debugging von Performance Problemen in .NET

Posted by on Wednesday, November 27, 2013

Die Analyse von Speicherproblemen ist eine Aufgabe die bei großen .NET Anwendungen häufiger vorkommt. In C++ wurde gesucht, wer welche Speicherblöcke angefordert und nicht wieder freigegeben hat und im .NET Umfeld wird eben gesucht warum der Gabarge-Collector den Speicher nicht freigeben kann. Oder man sucht warum einige Benutzeraktionen besonders lange benötigen. Für die Analyse gibt es eine ganze Reihe guter kommerzieller Programme, auf diese möchte ich jedoch nicht eingehen, sondern ein paar kostenlosen Alternativen vorstellen.

PerfView

Dieses Programm von Microsoft ist klein, schnell und leistungsfähig. Zum einen bietet es die Möglichkeit mittels ETW (Event Tracing for Windows) Problemen in der Laufzeit (CPU, I/O, GC) auf die Spur zu kommen. Zum anderen kann es Speicherabbilder von Programmen erzeugen und diese Vergleichen! Ausführliche Informationen gibt es bei Channel9 oder auf Vance Morrison’s Webblog.

WinDbg mit „_S_on _O_f _S_trikes“ Erweiterung

Microsoft liefert die sos.dll mit dem .NET Framework aus. Sie ermöglicht den WinDbg dazu managed Code zu debuggen. Für die den Themenkomplex WinDbg und SOS, gibt es viele gute Artikel/Tutorials von welchen ich zwei empfehlen möchte:

  1. Der Blog von Tess Ferrandez beispielsweise mit den Artikeln „.NET Finalizer Memory Leak“ und „New commands in SOS for 4.0“.
  2. Ein Blogeintrag von Rex Tang in welchem er weitere lesenswerte Artikel zu diesem Thema auflistet.

Auf der MSDN Webseite befindet sich die Befehlsreferenz.

WinDbg mit „SOSEX tension“ Erweiterung

Die von Steve Johnson geschriebene sosex.dll bietet viele nützliche Erweiterungen die dass managed Code debugging im WinDbg deutlich vereinfachen. Beispielsweise kann die SOSEX mittels Befehl !bhi einen HeapIndex erstellen lassen. Dieser Index enthält alle benötigten Informationen über die Objekte auf dem Heap. Um anschließend z.B. alle GC-Roots eines Objektes zu finden (!mroot <adr> -all) muss die SOSEX nicht das gesamte Speicherabbild analysieren sondern nur den HeapIndex. Dieses Vorgehen funktioniert deutlich schneller als die Alternative der SOS (!gcroot -all <adr>), welche jedes mal das Speicherabbild durchsucht.

Eine andere Eigenschaft ist das die SOSEX .prefer_dml 1 verwendet d.h. dass Links in die Ausgabe des WinDbg eingebettet werden. Dadurch wird einem häufig das kopieren bzw. abtippen von teilen der Ausgabe erspart.

Weitere Funktionalitäten der SOSEX sind

  • Anzeige von managed Locks und native CriticalSections (!mlocks)
  • Anzeige von wartenden Thread inkl. dem worauf sie warten (!mwaits)
  • Anzeige von Objekten in der Finalizer Queue (!finq)
  • Anzeige von Objekten in der F-Reachable Queue (!frq)

Lesen sie hier die Beschreibung des Unterschiedes zwischen Finalizer Queue und F-Reachable Quere.

Tip: Herr Johnson aktualisiert SOSEX regelmäßig, auch wenn er dazu keine Notiz auf seinen Blog hinterlässt. Deshalb lohnt es sich immer mal wieder das Zip-Archiv herunter zuladen und zu prüfen ob die enthaltene SOSEX neuer ist als die eigene.