Profilerstellungs- und Laufzeitbenachrichtigungs-IDs
Laufzeitbenachrichtigungen liefern eine ID für berichtete Klassen, Threads, Anwendungsdomänen usw. Diese IDs können verwendet werden, um weitere Informationen aus der Common Language Runtime (CLR) abzufragen. Jede ID ist die Adresse eines Blocks im Arbeitsspeicher, der das Element beschreibt. IDs sollten jedoch von Profilern als nicht transparente Handles behandelt werden. Wenn eine ungültige ID in einem Aufruf einer Profilerstellungsfunktion verwendet wird, sind die Ergebnisse nicht definiert. Am wahrscheinlichsten ist als Ergebnis eine Zugriffsverletzung. Der Profiler muss sicherstellen, dass die IDs, die verwendet werden, gültig sind. Die Profilerstellungs-API führt keinerlei Validierung durch, da dies zu Verwaltungsaufwand führen und die Ausführung der Anwendung beträchtlich verlangsamen würde.
In den folgenden Abschnitten werden die Eigenschaften von IDs in der Profilerstellungs-API beschrieben.
Eindeutigkeit
Eine ProcessID ist während der Lebensdauer des Prozesses systemweit eindeutig. Alle anderen IDs sind prozessweit während der Lebensdauer der ID eindeutig.
Hierarchie und Kapselung
IDs werden in einer Hierarchie angeordnet, die die Hierarchie im Prozess widerspiegelt. Prozesse enthalten Anwendungsdomänen, die Assemblys enthalten, die wiederum Module enthalten, die wiederum Klassen enthalten, die wiederum Funktionen enthalten. Threads sind innerhalb der Prozesse enthalten und werden möglicherweise von Anwendungsdomäne zu Anwendungsdomäne verschoben. Objekte sind zumeist innerhalb der Anwendungsdomänen enthalten, und einige wenige Objekte können gleichzeitig Mitglieder mehrerer Anwendungsdomänen sein. Kontexte sind innerhalb von Prozessen enthalten.
Lebensdauer und Stabilität
Wenn ein gegebener Prozess, eine gegebene Anwendungsdomäne, eine gegebene Assembly, ein gegebener Thread oder ein gegebenes Objekt zerstört, freigesetzt oder freigegeben werden oder enden, wird die damit verbundene ID ungültig. Wenn eine gegebene ID ungültig wird, werden alle IDs, die sie enthält, ebenfalls ungültig. Wenn beispielsweise eine Anwendungsdomäne entladen wird, wird ihre AppDomainID ungültig. Die AssemblyIDs, ModuleIDs, ClassIDs und FunctionIDs, die den Assemblys, Modulen, Klassen und Funktionen innerhalb der Anwendungsdomäne entsprechen, werden gleichzeitig ebenso ungültig.
Die Lebensdauer und die Stabilität bestimmter IDs ist im Folgenden aufgeführt:
ProcessID: Aktiv und stabil vom Aufruf der ICorProfilerCallback::Initialize-Methode bis zur Rückgabe von der ICorProfilerCallback::Shutdown-Methode.
AppDomainID: Aktiv und stabil vom Aufruf der ICorProfilerCallback::AppDomainCreationFinished-Methode bis zur Rückgabe von der ICorProfilerCallback::AppDomainShutdownStarted-Methode.
AssemblyID, ModuleID, ClassID: Aktiv und stabil vom Aufruf der LoadFinished-Methode für die ID bis zur Rückgabe von der UnloadStarted-Methode für die ID.
FunctionID: Aktiv und stabil vom Aufruf der ICorProfilerCallback::JITCompilationFinished-Methode oder der ICorProfilerCallback::JITCachedFunctionSearchFinished-Methode bis zur Zerstörung der ClassID, in der sie enthalten ist.
ThreadID: Aktiv und stabil vom Aufruf der ICorProfilerCallback::ThreadCreated-Methode bis zur Rückgabe von der ICorProfilerCallback::ThreadDestroyed-Methode.
ObjectID: Aktiv ab dem Aufruf der ICorProfilerCallback::ObjectAllocated-Methode. Freigegeben zum Ändern oder Löschen durch eine Garbage Collection.
GCHandleID: Aktiv ab dem Aufruf der ICorProfilerCallback2::HandleCreated-Methode bis zur Rückgabe von der ICorProfilerCallback2::HandleDestroyed-Methode.
Darüber hinaus sind alle IDs, die eine Profilerstellungsfunktion zurückgibt, zum Zeitpunkt der Rückgabe aktiv.
Anwendungsdomänenaffinität
Jede durch einen Benutzer erstellte Anwendungsdomäne in einem Prozess hat eine AppDomainID. Die Standarddomäne und eine spezielle Pseudodomäne, die für die Aufnahme domänenneutraler Assemblys verwendet wird, haben ebenfalls eine AppDomainID.
Assemblys, Module, Klassen, Funktionen und Garbage Collector-Handles verfügen über Anwendungsdomänenaffinität. Das bedeutet, dass die Assembly und alle ihre Module, Klassen, Funktionen und Garbage Collector-Handles beim Laden einer Assembly in mehrere Anwendungsdomänen in jeder Anwendungsdomäne eine andere ID haben können. Vorgänge, die für eine ID ausgeführt werden, wirken sich nur auf die damit verbundene Anwendungsdomäne aus. Domänenneutrale Assemblys werden in der speziellen Pseudodomäne angezeigt, wie bereits oben erwähnt.
Weitere Hinweise
Alle IDs mit Ausnahme von ObjectID sollten als nicht transparente Werte behandelt werden. Die meisten IDs sind ganz ohne Erläuterung verständlich. Die folgenden IDs sollen näher erklärt werden:
ClassIDs stellen Klassen dar. Im Fall von generischen Klassen stellen sie völlig instanziierte Typen dar. List<int>, List<char>, List<object> und List<string> verfügen jeweils über eine eigene ClassID. List<T> ist ein nicht instanziierter Typ und hat keine ClassID. Dictionary<string,V> ist ein teilweise instanziierter Typ und hat keine ClassID.
Eine FunctionID stellt systemeigenen Code für eine Funktion dar. Im Fall von generischen Funktionen (oder Funktionen in generischen Klassen) können mehrere systemeigene Codeinstanziierungen und damit mehrere FunctionIDs für eine gegebene Funktion vorhanden sein. Systemeigene Codeinstanziierungen können von verschiedenen Typen (z. B. List<string>-Freigabecode und List<object>-Freigabecode) gemeinsam genutzt werden, sodass eine FunctionID zu mehr als einer ClassID gehören kann.
ObjectIDs stellen Objekte dar, die der Garbage Collection unterliegen. Eine ObjectID ist die aktuelle Adresse eines Objekts zu dem Zeitpunkt, an dem der Profiler die ObjectID empfängt. Sie kann sich bei jeder Garbage Collection ändern. Daher ist ein ObjectID-Wert nur zwischen dem Zeitpunkt, an dem er empfangen wurde, und dem Zeitpunkt des Beginns der nächsten Garbage Collection gültig. Die CLR liefert auch Benachrichtigungen für einen Profiler zur Aktualisierung seiner internen Objektverfolgungszuordnungen, sodass der Profiler eine gültige ObjectID über die Garbage Collections hinaus verwalten kann.
GCHandleIDs stellen Einträge in der Handletabelle der Garbage Collection dar. Im Gegensatz zu ObjectIDs sind GCHandleIDs nicht transparente Werte. Garbage Collection-Handles werden in manchen Fällen von der CLR selbst erstellt. Sie können aber auch durch Verwendung der GCHandle-Struktur erstellt werden. (Beachten Sie, dass die GCHandle-Struktur das Handle nur darstellt; das Handle ist in der Struktur nicht enthalten.)
ThreadIDs stellen verwaltete Threads dar. Wenn ein Host die Ausführung im Fibermodus unterstützt, kann ein verwalteter Thread auf verschiedenen Betriebssystem-Threads vorhanden sein, abhängig davon, wann er überprüft wird.
Hinweis Die Profilerstellung für Fibermodus-Anwendungen wird in .NET Framework, Version 2.0, nicht unterstützt.