Dieser Artikel wurde maschinell übersetzt.

CLR von allen Seiten

Profilerstellung für den vom .NET Garbage Collector bereinigten Heap

S.Ramaswamy und V. Morrison

In der MSDN Magazine Juni 2009 Artikel Speicher Auditing für .NET Applications, Überwachung Speicherverbrauch mit Tools wie Task-Manager", "PerfMon" und "VADump erörtert. Diese Tools unterstützen in der gesamten Speicherverbrauch der Anwendung überwachen. In der Regel ist eine Anwendung .NET sehr viel Arbeitsspeicher verbraucht, entweder weil die Anwendung lädt eine große Anzahl von DLLs oder die Anwendung eine große Anzahl von langlebige Objekte auf dem Heap der .NET Garbage Collection (GC) erstellt wird. Wenn eine Anwendung viele DLLs lädt, wird nur Recourse (außer vermeiden, um unnötige Abhängigkeiten) weniger Code ausgeführt. Wenn eine Anwendung aus einer großen GC-Heap Speicherbedarf leidet, konnte eine identifizieren jedoch, dass im GC-Heap zu Speicherverbrauch, erheblich beitragen wurde wie in der Juni-Artikel beschrieben. In diesem Artikel schließen wir das Bild für GC-Heap-bezogene Speicherprobleme, indem Sie schrittweise Anweisungen zur Verwendung von CLR Profiler für .NET GC-Heap Speicher Untersuchungen.

Zusammenfassung: Überwachen Sie alle Anwendungen

Die .NET Runtime abstrahiert bestimmte Vorgänge (z. B. beim Reservieren von Speicher oder mithilfe einer großen-Klasse Bibliothek), und es ist nicht immer einfach, die Auswirkungen dieser Operationen auf die Anwendungsleistung vorhersehen. Dies gilt insbesondere für den Speicher. Wichtige Takeaway Punkt im letzten Artikel befand sich, dass jede Anwendung eine periodische Speicher Überwachung verdient. In diesem Artikel durchläuft diese detaillierte mit einem echten Programm wie in unserem Beispiel (im Gegensatz zu einer Demo). Dies war ein einfaches Programm, und wir konnte gewählt haben keine Speichernutzung ’s Anwendung überwachen. Allerdings wir nach Abschluss eine Überwachung Speicher bezahlt der geringe Aufwand Durchführen der Überwachung handsomely, wie wir erhebliche Speicher Ineffizienz gefunden.

Die Anwendung, die wir in diesem Artikel verwenden heißt XMLView, dem einfachen Viewer für XML-Dateien handelt, hochgradig skalierbare. XMLView kann problemlos bewältigen XML-Dateien, Gigabyte groß sind (versuchen, in Internet Explorer!), da diese Anwendung entwickelt wurde, werden Speicher effizient von Anfang an. Trotz der sorgfältigen Entwurf in einigen Szenarios zeigte Tools wie Task-Manager, dass die Anwendung wesentlich mehr Speicher als wir erwartet haben würde verwendet wurde. Dieser Artikel führt Sie durch die Untersuchung, die einen Fehler Leistung aufgedeckt.

Große Grafik Speichernutzung

Die erste Schritt in einem Speicher Überwachung besteht darin, starten Sie die Anwendung und Betrachten der OS Task-Manager allgemeine Speichernutzung der Anwendung ’s überprüfen. Wie zuvor beschrieben, ist die Metrik, die am wichtigsten ist die "Speicher - private arbeiten festlegen"Spalte. Dies bezieht sich auf die Anwendungs-Speicheroptimierung mit anderen auf dem Computer ausgeführten Prozesse gemeinsam verwendet werden kann (siehe vorherigen Artikel Einzelheiten).

Sobald Task-Manager geöffnet ist, können die privaten Speichernutzung der Anwendung in Echtzeit überwachen, führen Sie verschiedene Benutzerszenarien und Auswirkungen auf die Speicherbelegung beobachten. Es gibt zwei Anomalien, die Ihre Aufmerksamkeit erfordern. Speicherbedarf, die auf das Szenario oder die momentan ausgeführten Aufgabe unverhältnismäßig großem ist. Beispielsweise sollten einen Menüeintrag im öffnen oder einfache Vorgänge führen nicht große Spitzen in Speicherverbrauch. Speicherlecks sind die zweite Anomalie, die Aufmerksamkeit erforderlich. Für einige Operationen, wie das Öffnen einer neuen Datei ist der Annahme, dass neue Datenstrukturen erstellt werden jedes Mal die Operationen ausgeführt wird. Viele Operationen (z. B. Suchvorgänge) werden jedoch nicht logisch neue langlebige Arbeitsspeicher reservieren. Es ist nicht ungewöhnlich, dass für diese statusfreien Operationen Arbeitsspeicher zum ersten Mal werden, das Sie ausgeführt werden (wie lazy Datenstrukturen aufgefüllt wurden). Aber wenn Speichernutzung mit nachfolgenden Iterationen des Szenarios zu erhöhen weiterhin, Speicher wird nicht wieder freigibt und untersucht werden soll. Diese Technik Verwendung des Task-Managers ist entwurfsbedingt sehr grober (nur großen Arbeitsspeicherprobleme werden offensichtlich), aber für viele Anwendungen sind nur die großen Dateien lohnt verfolgt.

Das Szenario ist für XMLView starten den Viewer auf eine große XML-Datei und Navigation-Operationen, z. B. Öffnen Strukturknoten oder Suche ausführen. Dieses Experiment eingestellt anfänglich keine Speicherverluste (die Speicherauslastung stabilisiert nach einer Weile;Abbildung 1 siehe). Belegung des Speichers statt erheblich spiked (8 MB) war die Suchfunktion (siehe Abbildung 2) zum 25648KB aus 16812KB privater Arbeitssatz verwendet. Dies stellt eine der Anomalien, die wir gesuchte dar: Der Ressourcenverbrauch passten nicht unsere Ihre Modell des ’s Programm Speicher Verhalten, da Suche keine zusätzlichen Datenstrukturen hat und sollte daher nicht zusätzlichen Arbeitsspeicher beansprucht. Wir hatten ein Mysterium lösen.


Abbildung 1 XMLView Speichernutzung im Task-Manager vor Suchoperation


Abbildung 2 XMLView Speichernutzung im Task-Manager nach Suchoperation

CLR Profiler

Eine Reihe von Tools von Drittanbietern sind verfügbar für die Analyse von .NET GC-Heap;Wir werden jedoch auf CLR Profiler konzentrieren über den Vorteil, als kostenloser Webdownload von Microsoft zur Verfügung stehen. Eine Websuche auf "CLR Profiler"wird die Download-Website suchen, und die Installation besteht lediglich entzippen der Dateien (Es gibt keine formale Installation Schritt). Als Teil des Pakets enthalten, stellt die Datei CLR Profiler.doc die Dokumentation bereit. In diesem Artikel Schwerpunkt auf die Teile, die häufig verwendet werden.

Wie funktioniert die CLR Profiler?

Um einen Profiler ordnungsgemäß verwenden, müssen Sie verstehen, wie die Daten gesammelt wurde und die Einschränkungen für das Tool. Die CLR Profiler verwendet eine spezielle Schnittstelle zur Laufzeit, die um Rückrufe zu erhalten, wenn bestimmte Ereignisse innerhalb der Common Language Runtime (msdn.microsoft.com/library/ms404511.aspx) ermöglicht. Derzeit kann diese Schnittstelle verwendet werden, nur, wenn der Prozess, die profiliert werden gestartet wird, mit bestimmten Umgebung Variablen, die die Runtime hinsichtlich der Kontakt Mechanismus der Profiler informieren. Daher gelten einige Einschränkungen, z. B. die Unfähigkeit, an einen vorhandenen Prozess angefügt. CLR Profiler müssen den Prozess mit dem richtigen Umgebung Variablen starten. Für Dienste, die normalerweise vom Betriebssystem direkt, wie ASP.NET, gestartet werden müssen besondere Verfahren befolgt werden (Siehe CLR Profiler.doc aus der Download für Details). Übrigens fügen für bestimmte Szenarien, denen wir API-Unterstützung für hinzugefügt haben, in der .NET Framework-4 (jedoch nur die API-Unterstützung;Unterstützung für das Tool CLR Profiler anfügen wird bald nach folgen).

Wenn CLR Profiler die Anwendung gestartet wird, bietet es die Optionen auf die Art der gesammelten Informationen. Standardmäßig wird Rückrufe jedes Mal eine verwaltete Methode aufgerufen wird, oder gibt, aus einem Aufruf, wie gut wie auf jede Heapzuweisung GC zurück. Diese Rückrufe werden oft aufgerufen, führt das Programm erheblich verlangsamen und Erstellen von großen Protokoll Dateien mehr als 100 MB) für viele reale Szenarios. CLR Profiler Ausführungszeit nicht messen und beschränkt sich selbst nur GC Heapzuweisungen verfolgen und die Anzahl wie oft jede andere Methode aufgerufen wurde. CLR Profiler verwendet die Methodenaufruf und Methode Return Ereignisse zu verfolgen welche Methoden auf dem Stapel aktiven sind, sodass jeder Aufruf und Heap-Zuordnung mit einer vollständige Aufrufliste der, in dem das Ereignis geschieht zugeschrieben werden kann. Identifiziert, in dem die Objekte erstellt werden.

Leider kann die detaillierte Informationen, die CLR Profiler standardmäßig sammelt die Datensammlungsprozess sehr langsam (Minuten) vornehmen. Diese detaillierten Informationen ist jedoch nur selten erforderlich. Eines der nützlichsten Verfahren erfordert keine zusätzliche Informationen, die während der normalen Ausführung gesammelt werden sollen. Es ist, zwar wichtig zu wissen, wo Speicherreservierung auftritt können viele Fehler nur durch Verständnis behoben werden, die Speicher aktiv halten. Diese zweite Frage müssen eine nicht Stapeln oder Zuweisung Ereignisse; aufgerufenVielmehr ist nur ein einfacher Snapshot der GC-Heap erforderlich. Daher kann eine für die meisten Untersuchungen alle normalen Ereignisprotokollierung deaktivieren und erhalten eine gute Erfahrung (angemessenen Profilerstellung der Leistung sowie das Problem identifizieren). Dies ist die hier verwendete Technik.

Mithilfe von CLR Profiler

Wenn Sie CLR Profiler aus dem Internet herunterladen und in den standardmäßigen Speicherort extrahieren, wird das Programm bis in C:\CLR Profiler\Binaries\x86\ClrProfiler.exe beenden (es ist ein x64-Version zu). CLR Profiler starten, wird das Formular im Abbildung 3 angezeigt.


Abbildung 3 CLR Profiler Start Bildschirm

Dieses Dialogfeld beim Start steuert die Auflistung der Profildaten. Die Kontrollkästchen zeigen an, wenn die Anwendung ausgeführt wird, Profilerstellung aktive werden und Zuweisung und Aufruf Daten werden gesammelt (die Protokolldatei wird ausführlich sein). Da wir nur Heap Snapshots interessiert sind, nur das Profiling active Feld muss aktiviert bleiben (die Felder Zuweisungen und Aufrufe sollte deaktiviert sein). Daher protokolliert die CLR Profiler nur das absolute Minimum während der Programmausführung Reaktionsfähigkeit beibehalten und Protokolldatei Größen, nach unten.

Wenn die Anwendung, die Sie Profil möchten, keine Befehlszeilenargumente oder spezielle Autostart-Verzeichnis benötigt, aktivieren Sie einfach Anwendung starten und CLR Profiler wird ein Dateidialogfeld für die Auswahl auf die Ausführung der Anwendung anzuzeigen. Wenn Sie Befehlszeilenparameter oder das aktuelle Verzeichnis für die Anwendung festlegen möchten, sollten Sie diese festlegen mithilfe der Datei - >Legen Sie im Menü Parameter, bevor Sie auf Anwendung starten.

Übernehmen eines Snapshots Heap

Nachdem Sie die ausführbare Anwendung ausgewählt, wird CLR Profiler sofort Ausführen der Anwendung. Da wir Reservierung und Aufruf Profilerstellung deaktiviert haben, sollten Sie sehr nahe an seine normale Geschwindigkeit ausführen. CLR Profiler jetzt an die Anwendung, und zu einem beliebigen Zeitpunkt können Sie wählen anzeigen Heap und erhalten einen Heap-Snapshot. Der Heap-Snapshot für die Anwendung XMLView geschieht mit aussehen, was im Abbildung 4 angezeigt wird.

Dies ist eine Darstellung des gesamten GC-Heaps (nur aktive Objekte werden angezeigt). Während der GC-Heap tatsächlich ein beliebiges Diagramm ist, bestimmt CLR Profiler Verknüpfungen und Formulare eine Struktur, es in eine Pseudo-node aufgerufen Stamm Stamm. Die Größe der einzelnen untergeordneten Elemente kann dann Ihre Eltern zugeschrieben werden so, dass im Stammverzeichnis alle aktiven Objekte für nachkalkuliert wurde haben. In dem obigen Beispiel musste der GC-Heap 5.4 MB von Objekten. Diese 5.4 MB enthält keinen freien Speicherplatz im GC-Heap, der nicht reserviert und daher des virtuellen Arbeitsspeichers für den Heap reserviert ist garantiert größer (die genaue Größe hängt, aber wie im vorherigen Artikel erwähnt, 1,6 viermal so groß ist eine gute Schätzung).

Es ist häufig mehr als einen einzigen Pfad vom Stamm zu einem bestimmten Objekt. CLR Profiler wählt immer den kürzesten Pfad für die Anzeige in der Struktur. Wenn mehrere Pfade mit derselben Länge vorhanden sind, wird die Auswahl jedoch willkürlich vorgenommen. Darüber hinaus standardmäßig CLR Profiler zeigt keine einzelnen Objekte jedoch behandelt alle Objekte, die dieselben übergeordneten Typen und die gleichen untergeordneten Typen als Teil der gleichen Knoten verfügen. Diese Technik wird im Allgemeinen ein guter Auftrag der Knoten verknüpfte Listen und anderen Datenstrukturen rekursive, vereinfachen dadurch die Ansicht reduzieren. Wenn diese Aggregation nicht erwünscht ist, können Sie es deaktivieren, indem Sie mit der rechten Maustaste und Auswählen einzelner Instanzen anzeigen.

Im oberen Bereich des Fensters "Heap Graph befinden sich zwei Optionsfeldgruppen. Der erste ist die Skalierung die Höhe jedes Feld in der Diagrammansicht gibt. Der zweite ist die Schaltfläche Details, die bestimmt, wie groß ein Knoten hat sein, um angezeigt zu erhalten. Es empfiehlt sich, dies ein sehr grober, damit das Diagramm ordentlichen festgelegt. Häufig sind Sie interessiert nur das Diagramm, das etwas mit einem bestimmten Typ (z. B. nur über Objekte des Typs XmlPositions) zu tun hat. CLR Profiler können Sie auf diesem und anderen Kriterien filtern (klicken Sie rechts - >Filter).

Im Beispiel XMLView im Abbildung 4 ist der Großteil der GC-Heap (5.1 MB) ein untergeordnetes Element einer Instanz der XmlView-Typ. Die XmlView-Instanz hat ein untergeordnetes Element des Typs XmlPositions, die wiederum einer 5 MB-XmlElementPositionInfo-Array verfügt. XmlElementPositionInfo des großen Arrays, die den Anfangspunkt in der Datei des jedes XML-Tag ist und seine Größe proportional zur Größe der gelesenen XML-Datei (da dies eine sehr große Datei ist, es wird erwartet, dass dieses Array groß werden). Folglich abgeschlossen wir die Heapgröße sinnvoll ist.


Abbildung 4 CLR Profiler Snapshot vor Suchoperation

Nachverfolgen von unten GC-Heap vergrößern

Im Beispiel XMLView war das Problem nicht mit der anfänglichen Größe des GC-Heap, sondern die Tatsache, die es erheblich vergrößert wurde, wenn eine Suche durchgeführt wurde. Was wir interessiert sind daher ist die Änderung in den Heap zwischen zwei Snapshots. CLR Profiler verfügt über spezielle Features nur für diese Art der Untersuchung ausführen.

Nach dem Erstellen einer Heap-Snapshots können wir dann durchführen der Suche (verursacht den zusätzlichen Arbeitsspeicher reserviert werden), und erstellen Sie eine andere Heap-Snapshot. Das Ergebnis ist die folgende Anzeige:

Der XmlView-Objekt zugeordneten Arbeitsspeicher wurde jetzt auf 8.5 MB (von 5.1 MB) erweitert. Die Knoten besitzen zwei Farben mit der heller rote, darstellt, des Speichers, der in der vorherige Snapshot vorhanden war. Dunkler rot ist der Speicher, der für den neuen Snapshot eindeutig ist. Daher wurde der neue Speicher hinzugefügt, durch einen Aufruf XmlFind (Dies ist nicht überraschend), wie in Abbildung 5 gesehen werden können. Bildlauf über das Recht, suchen wir, dass alle dieser zusätzlichen Arbeitsspeicher mit einem zugeordneten war, die in den Typ LineStream, als in Abbildung 6 gehörten.

Dies wurde die Informationen für den Fehler zu identifizieren. Wie sich herausstellt, dass der .NET XML-Parser die Möglichkeit, die Zeile Nummer Spalte Anzahl der XML-Tags, aber nicht die Dateiposition abzurufen ist. Dieses Problem umgehen, benötigt die Anwendung eine Zuordnung zwischen Zeilennummer Dateiposition. Int64-Array wurde verwendet. Jedoch benötigt der Code diese Zuordnung nur für das aktuelle XML-Elementtag, das eine beliebige Anzahl Zeilen, aber in der Regel nur wenige erstrecken kann. Diese Zuordnung wurde nicht durch den Code suchen, wodurch das Array Zuordnung unnötig groß zurückgesetzt wird. Das Update war einfach, aber dieser Fehler würde wahrscheinlich haben war immer wenn die Speicher-Überwachung nicht durchgeführt wurde. CLR Profiler verwenden, hat die Informationen finden, die wichtig für diesen Fehler zu beheben war nur ein paar Minuten gedauert.


Abbildung 5 CLR Profiler nach Suchoperation Snapshot - Teil 1


Abbildung 6 CLR Profiler nach Suchoperation Snapshot - Teil 2

Der neue Objekte Alone anzeigen

Im vorherigen Beispiel war es relativ einfach, visuell durch ihre Farbe die Objekte für den letzten Snapshot eindeutig unterscheiden. Allerdings bei großer Objektgraphen ist dies nur schwer zu tun und wäre es sinnvoll, die alte Objekte aus dem Diagramm, vollständig zu entfernen, kann erfolgen mithilfe von CLR Profiler. Dieses Feature verwendet die Reservierung Ereignisse für die Implementierung, nach dem Erstellen des ersten Snapshots benötigen Sie das Zuordnungen Kontrollkästchen (Sie können das Aufrufe Feld deaktiviert lassen). Folgende, interagieren mit der Anwendung, bis es mehr Speicher reserviert, und wählen Sie erneut Heap jetzt anzeigen. Es wird wie zuvor den Heap mit seinen zwei Farben von Rot angezeigt. Jetzt, Sie können mit der rechten Maustaste auf das Fenster und wählen Sie neue Objekte anzeigen, und einem neues Fenster angezeigt, die nur den Teil des GC-Heap zeigt, der zwischen zwei Snapshots reserviert wurde.

Unten alle Stämme überwachen für ein Objekt

Sie fragen sich vielleicht wie Speicher, die Speicherverluste in verwaltetem Code, der Garbage Collector schließlich erhält erfolgen können alle nicht verwendeten Speicherplatz bereinigt. Es gibt jedoch Situationen, in denen Elemente aktiv bleiben können, lange nach dem Sie vielleicht denken Sie freigegeben werden. Z. B. möglicherweise unbeabsichtigten Verweise auf verwaltete Objekte aufrechtzuerhalten.

Das Verfahren für das Aufspüren Speicherverluste ist sehr ähnlich, für das Verständnis unverhältnismäßig großem Speicherbedarf. Der einzige wirkliche Unterschied liegt darin, dass für unverhältnismäßig großem Speicherbedarf wir das Objekt im Speicher erwarten (es sollte nur nicht so groß sein), wohingegen undichte, wir nicht das Objekt in den GC-Heap überhaupt erwarten. Heap-Snapshots und die neuen Objekte anzeigen-Funktion verwenden, ist es einfach ermitteln, welche Objekte nicht aktiv (über Ihre Kenntnisse über das Szenario) werden sollen. Wenn ein Objekt im Heap weiterhin bestehenden ist, müssen einige Verweis auf das Objekt sein. Allerdings wird mehr als einen einzelnen Verweis, Sie vielleicht Entfernen einer Verknüpfung nicht das Problem behoben werden weil eine andere Referenz es aktiv beibehalten wird. Folglich wäre es sinnvoll, alle Pfade aus dem Stammverzeichnis zu finden, die ein bestimmtes Objekt in den GC-Heap beibehalten. CLR Profiler verfügt über speziellen Unterstützung dafür. Zunächst wird der Knoten von Interesse ausgewählt. Klicken Sie mit der rechten Maustaste auf, und wählen anzeigen Verweise und ein neues Diagramm angezeigt, die alle Pfade aus dem Stammverzeichnis für das Objekt betreffende anzeigt. Dies wird Sie mit genügend Informationen zur Identifizierung bereitstellen welche Verweise die Objekte im Heap aktiv beibehalten werden. Vermeiden die Verknüpfungen zu dem Objekt kann Ihre Speicherverlust beheben.

Erste Zuweisung Aufruf-Stacks

Anzeigen den GC-Heap ist häufig ausreichend, um die meisten hoher Speicherverbrauch Probleme diagnostizieren. Es ist jedoch gelegentlich nützlich, um die Aufrufliste zu verstehen, wo eine Zuordnung aufgetreten ist. Um die Informationen abzurufen, müssen Sie das Kontrollkästchen Zuordnungen vor dem Ausführen des Programms auswählen. Dadurch wird die CLR Profiler die Stapelüberwachung anmelden, sobald eine Reservierung erfolgt. Diese Informationen werden gesammelt wird vergrößern die Protokolldatei wird, aber es weiterhin in der Regel weniger als 50 MB für mäßig komplexen Anwendungen. Sie sollten nicht auf das Kontrollkästchen Anrufe aktivieren, da dies bewirkt, dass jeder Eintrag-Methode, die ausführliche anmelden (es ist leicht Protokolldateien größer als 100 MB). Diese Methode Anrufinformationen wird benötigt, nur bei Verwendung CLR Profiler um festzustellen, welche Methoden häufig aufgerufen werden, und dies ist nicht in der Regel in eine Untersuchung Speicher nutzen.

Die Heapkurve Wählen Sie einen Knoten des Zinsen, klicken Sie mit der rechten Maustaste und wählen Sie anzeigen, die zugewiesene. Ein neues Fenster zeigt alle Aufrufe-Stapel, die ein Objekt in diesem Knoten zugeordnet werden angezeigt. Sie können die Stapelüberwachungen auch zugreifen, aus der Ansicht - >Allocation Graph Menüelement. Zeigt alle während der Anwendung der Aufrufliste, die Ihnen zugewiesenen zugeordnet vorgenommene Zuordnungen. Für Speicher Untersuchungen ist diese Ansicht sehr nützlich, da viele dieser Zuordnungen für kurzlebige Objekte sind, die schnell vom GC zurückgefordert erhalten, und daher nicht zum gesamten Speicherverbrauch beiträgt. Jedoch seit diese Zuordnungen tragen zu CPU-Auslastung (zum Zuordnen und dann freizugeben), ist diese Ansicht hilfreich, wenn Ihre Anwendung CPU-gebundenen ist und der CPU-Profiler Zeigt große Mengen an Zeit wird in den globalen Katalog. Offensichtliche Möglichkeit zum Kürzen von Ausfallzeiten in die FREISPEICHERSAMMLUNG besteht darin, weniger Zuordnungen und diese Ansicht zeigt die Aufrufliste, wobei die Zuweisungen sind.

Teil des Sicherheitsentwicklungszyklus

In diesem Artikel durchgegangen wir einer Leistungsuntersuchung Speicher für den allgemeinen Fall, in denen der Arbeitsspeicherverbrauch durch .NET GC-Heap dominiert wird. Verwenden die freien und downloadbaren CLR Profiler, konnten wir leicht zum Abrufen von Snapshots der GC-Heap an verschiedenen Punkten in der Anwendung und die Snapshots miteinander vergleichen. Mit CLR Profiler ist leicht zu Überwachungen durchführen (Dies dauert nur wenige Minuten) und sollte Teil des Entwicklungslebenszyklus jeder Anwendung sein.

Subramanian Ramaswamy* ist Programmmanager für CLR-Leistung bei Microsoft. Er enthält einen Bereich elektrischen und Computer Engineering von Georgia Institute of Technology.*

Vance Morrison* ist der Partner--Architekt und der Gruppe Manager für CLR-Leistung bei Microsoft. Er steuerte den Entwurf der .NET Intermediate Language und wurde seit seiner Einführung mit .NET.*