Debug e ottimizzazione JIT
Se si sta tentando di eseguire il debug del codice, è più semplice quando il codice non è ottimizzato. Quando il codice è ottimizzato, il compilatore e il runtime apportano modifiche al codice CPU generato in modo che venga eseguito più velocemente, ma ha un mapping meno diretto al codice sorgente originale. Se il mapping è meno diretto, i debugger spesso non sono in grado di indicare il valore delle variabili locali e i passaggi del codice e i punti di interruzione potrebbero non funzionare come previsto.
Nota
Per altre informazioni sul debug JIT (Just In Time), leggere questa documentazione.
Funzionamento delle ottimizzazioni in .NET
In genere, la configurazione della build di rilascio crea codice ottimizzato e la configurazione della build di debug non lo fa. La Optimize
proprietà MSBuild controlla se al compilatore viene chiesto di ottimizzare il codice.
Nell'ecosistema .NET il codice viene trasformato dall'origine alle istruzioni della CPU in un processo in due passaggi: innanzitutto, il compilatore C# converte il testo digitato in un formato binario intermedio denominato MSIL e scrive il codice MSIL in .dll file. Successivamente, il runtime .NET converte questo MSIL in istruzioni della CPU. Entrambi i passaggi possono essere ottimizzati in qualche modo, ma il secondo passaggio eseguito dal runtime .NET esegue le ottimizzazioni più significative.
Opzione 'Suppress JIT optimization on module load (Managed only)' (Elimina l'ottimizzazione JIT al caricamento del modulo (solo gestito)"
Il debugger espone un'opzione che controlla cosa accade quando una DLL compilata con ottimizzazioni abilitate carica all'interno del processo di destinazione. Se questa opzione è deselezionata (stato predefinito), quando .NET Runtime compila il codice MSIL nel codice CPU, lascia abilitate le ottimizzazioni. Se l'opzione è selezionata, il debugger richiede che le ottimizzazioni siano disabilitate.
Per trovare l'opzione Elimina ottimizzazione JIT al caricamento del modulo (solo gestito), selezionare Opzioni strumenti>e quindi selezionare la pagina Generale nel nodo Debug.
Quando è necessario selezionare l'opzione 'Elimina ottimizzazione JIT'?
Selezionare questa opzione quando sono state scaricate le DLL da un'altra origine, ad esempio un pacchetto nuget e si vuole eseguire il debug del codice in questa DLL. Per il corretto funzionamento dell'eliminazione, è necessario trovare anche il file simbolo (con estensione pdb) per questa DLL.
Se si è interessati solo al debug del codice che si sta creando in locale, è consigliabile lasciare deselezionata questa opzione, perché, in alcuni casi, l'abilitazione di questa opzione rallenterà notevolmente il debug. Esistono due motivi per cui questo rallentamento:
- Il codice ottimizzato viene eseguito più velocemente. Se si disattivano le ottimizzazioni per un numero elevato di codice, l'impatto sulle prestazioni può aumentare.
- Se Just My Code è abilitato, il debugger non tenterà nemmeno di caricare i simboli per le DLL ottimizzate. La ricerca dei simboli può richiedere molto tempo.
Limitazioni dell'opzione 'Elimina ottimizzazione JIT'
L'attivazione di questa opzione non funziona in due situazioni:
In situazioni in cui si collega il debugger a un processo già in esecuzione, questa opzione non avrà alcun effetto sui moduli già caricati al momento del collegamento del debugger.
Questa opzione non ha alcun effetto sulle DLL precompilata (o ngen'ed) nel codice nativo. Tuttavia, è possibile disabilitare l'utilizzo del codice precompilato avviando il processo con la variabile di ambiente 'COMPlus_ReadyToRun' impostata su '0'. Questo indicherà al runtime di .NET Core di disabilitare l'uso di immagini precompilato, forzando il runtime a compilare il codice del framework JIT.
Se si ha come destinazione .NET Framework, aggiungere la variabile di ambiente 'COMPlus_ZapDisable' e impostarla su '1'.
Impostarlo "COMPlus_ReadyToRun": "0"
aggiungendolo a ogni profilo nel file Properties\launch Impostazioni.json:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59694/",
"sslPort": 44320
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"COMPlus_ReadyToRun": "0"
}
},
"HttpLoggingSample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"COMPlus_ReadyToRun": "0"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}