ID notifica profilatura e runtime
E notifiche runtime forniscono un ID per le classi, i thread, i domini applicazione riportati e così via. Ali ID possono essere utilizzati per eseguire una query per ottenere ulteriori informazioni sul Language Runtime comune (CLR). Ogni ID è l'indirizzo di un blocco di memoria che descrive l'elemento. Tuttavia, gli ID devono essere trattati come handle opachi dai profiler. Se in una chiamata a una funzione di analisi viene utilizzato un ID non valido, i risultati saranno indefiniti. È probabile che il risultato sarà una violazione di accesso. Il profiler deve verificare che gli ID utilizzati siano validi. L'API di analisi non esegue alcun tipo di convalida, perché creerebbe un sovraccarico e potrebbe notevolmente rallentare l'esecuzione dell'applicazione.
Nelle sezioni seguenti vengono descritte le caratteristiche degli ID nell'API di analisi.
Univocità
Un ProcessID è univoco in tutto il sistema per la durata del processo. Tutti gli altri ID sono univoci a livello di processo per la durata dell’ID.
Gerarchia e contenimento
Gli ID sono organizzati in una gerarchia che rispecchia la gerarchia nel processo. I processi contengono domini applicazione che contengono assembly che contengono moduli che contengono classi che contengono funzioni. I thread sono contenuti all'interno di processi e possono spostarsi da un dominio applicazione a un altro. Gli oggetti sono per lo più contenuti all'interno di domini applicazione e molto pochi oggetti possono essere contemporaneamente membri di più domini applicazione. I contesti sono contenuti all'interno di processi.
Durata e stabilità
Quando un processo, dominio applicazione, assembly, thread o oggetto specificato viene eliminato in modo permanente, liberato, rilasciato o termina, l’ID associato diventerà non valido. Quando un ID specificato diventa non valido, diventeranno non validi anche tutti gli ID contenuti in esso. Ad esempio, quando un dominio applicazione viene scaricato, il relativo AppDomainID diviene non valido. AssemblyID, ModuleID, ClassID e FunctionID che corrispondono agli assembly, ai moduli, alle classi e alle funzioni all'interno del dominio applicazione diventeranno anch’essi non validi.
La durata e la stabilità degli ID specifici sono le seguenti:
ProcessID: attivo e stabile dalla chiamata al metodo ICorProfilerCallback::Initialize fino al ritorno dal metodo ICorProfilerCallback::Shutdown.
AppDomainID: attivo e stabile dalla chiamata al metodo ICorProfilerCallback::AppDomainCreationFinished fino al ritorno dal metodo ICorProfilerCallback::AppDomainShutdownStarted.
AssemblyID, ModuleIDClassID: attivo e stabile dalla chiamata al metodo LoadFinished per l’ID fino al ritorno dal metodo UnloadStarted per l’ID.
FunctionID: attivo e stabile dalla chiamata al metodo ICorProfilerCallback::JITCompilationFinished o ICorProfilerCallback::JITCachedFunctionSearchFinished fino alla distruzione del ClassID che lo contiene.
ThreadID: attivo e stabile dalla chiamata al metodo ICorProfilerCallback::ThreadCreated fino al ritorno dal metodo ICorProfilerCallback::ThreadDestroyed.
ObjectID: attivo a partire dalla chiamata al metodo ICorProfilerCallback::ObjectAllocated. Idoneo a modifica o annullamento con ogni Garbage Collection.
GCHandleID: attivo dalla chiamata al metodo ICorProfilerCallback2::HandleCreated fino al ritorno dal metodo ICorProfilerCallback2::HandleDestroyed.
Inoltre, qualsiasi ID restituito da una funzione di analisi sarà attivo al momento della restituzione.
Affinità del dominio applicazione
Ogni dominio applicazione creato dall'utente in un processo ha un AppDomainID. Il dominio predefinito e uno speciale pseudodominio utilizzati per contenere assembly indipendenti dal dominio hanno anche un AppDomainIDs.
Assembly, moduli, classi, funzioni e handle di Garbage Collector hanno un'affinità del dominio applicazione. In altri termini, se un assembly viene caricato in più domini applicazione, l'assembly e tutti i suoi moduli, classi, funzioni e handle di Garbage Collector avranno un ID diverso in ogni dominio applicazione e le operazioni su ciascun ID saranno effettive soltanto nel dominio applicazione associato. Assembly indipendenti dal dominio sono visualizzati nello speciale pseudo dominio indicato in precedenza.
Note aggiuntive
Tutti gli ID tranne ObjectID devono essere trattati come valori opachi. La maggior parte degli ID non necessita di ulteriori spiegazioni. I seguenti ID meritano una spiegazione più approfondita:
I ClassID rappresentano le classi. Nel caso di classi generiche, rappresentano tipi completamente dotati di istanze. Gli oggetti List<int>, List<char>, List<object> e List<string> dispongono ognuno del relativo oggetto ClassID. List<T> è un tipo privo di istanze e non dispone di un oggetto ClassID. Dictionary<string,V> è un tipo con istanze parziali e non dispone di un oggetto ClassID.
I FunctionID rappresentano il codice nativo per una funzione. Nel caso di funzioni generiche (o funzioni sulle classi generiche), possono esistere più creazioni di istanze del codice nativo e quindi più FunctionID per una funzione specificata. Le creazioni di istanze del codice nativo possono essere condivise tra tipi diversi (ad esempio, List<string> e List<object> condividono il codice), quindi un FunctionID può appartenere a più di un ClassID.
Gli ObjectID rappresentano oggetti sottoposti a procedure di Garbage Collection. Un ObjectID è l'indirizzo corrente di un oggetto quando il profiler riceve l’ObjectID e può esser diverso in ogni Garbage Collection. Di conseguenza, un valore di ObjectID è valido solo tra il momento in cui viene ricevuto e il momento in cui inizia l’operazione successiva di Garbage Collection. CLR fornisce anche notifiche per consentire a un profiler di aggiornare le mappe interne di rilevamento degli oggetti, in modo tale da poter gestire un ObjectID valido in diverse operazioni di Garbage Collection.
I valori GCHandleID rappresentano le voci nella tabella degli handle di Garbage Collection. I valori GCHandleID, a differenza di ObjectID, sono valori opachi. Gli handle della Garbage Collection sono in alcuni casi creati dallo stesso CLR o possono essere creati utilizzando la struttura GCHandle. (Si noti che la struttura GCHandle rappresenta solo l’handle, che non è contenuto nella struttura.)
I ThreadID rappresentano i thread gestiti. Se un host supporta l’esecuzione in modalità fiber, un thread gestito può esistere su diversi thread del sistema operativo, a seconda del momento in cui viene esaminato.
Nota L'analisi delle applicazioni in modalità fiber non è supportata in .NET Framework versione 2.0.