Otimização e depuração JIT
Se você estiver tentando depurar o código, será mais fácil quando esse código NÃO for otimizado. Quando o código é otimizado, o compilador e o runtime fazem alterações no código de CPU emitido para que ele seja executado mais rapidamente, mas tenha um mapeamento menos direto para o código-fonte original. Se o mapeamento for menos direto, os depuradores frequentemente não poderão informar o valor das variáveis locais e os pontos de interrupção e de etapa de código poderão não funcionar conforme o esperado.
Observação
Para obter mais informações sobre a depuração JIT (Just-In-Time), leia esta documentação.
Como as otimizações funcionam no .NET
Normalmente, a configuração de build de versão cria código otimizado, o que não acontece na configuração de build de depuração. A propriedade MSBuild Optimize
controla se o compilador é orientado a otimizar o código.
No ecossistema do .NET, o código é transformado da origem para as instruções da CPU em um processo de duas etapas: primeiro, o compilador C# converte o texto que você digita em um formulário binário intermediário chamado MSIL e grava o MSIL para arquivos .dll. Posteriormente, o Runtime do .NET converte essa MSIL em instruções de CPU. Ambas as etapas podem ser otimizadas até certo ponto, mas a segunda etapa executada pelo Runtime do .NET executa as otimizações mais significativas.
A opção 'Suprimir otimização JIT no carregamento do módulo (somente gerenciado)'
O depurador expõe uma opção que controla o que acontece quando uma DLL compilada com otimizações habilitadas carrega dentro do processo de destino. Se essa opção estiver desmarcada (o estado padrão), quando o Runtime do .NET compilar o código MSIL no código da CPU, ela deixará as otimizações habilitadas. Se a opção for verificada, o depurador solicitará que as otimizações sejam desabilitadas.
Para localizar a opção Suprimir otimização JIT no carregamento do módulo (somente gerenciado), selecione Ferramentas>Opções e, em seguida, selecione a página Geral no nó Depuração.
Quando você deve verificar a opção 'Suprimir otimização JIT'?
Verifique essa opção quando você baixou as DLLs de outra fonte, como um pacote nuget, e deseja depurar o código nesta DLL. Para que a supressão funcione, você também deve encontrar o arquivo de símbolo (.pdb) para essa DLL.
Se você estiver interessado apenas em depurar o código que está criando localmente, é melhor deixar essa opção desmarcada, pois, em alguns casos, habilitar essa opção reduzirá significativamente a depuração. Há dois motivos para essa redução:
- O código otimizado é executado mais rapidamente. Se você estiver desativando otimizações para muitos códigos, o impacto no desempenho poderá ser somado.
- Se você tiver Apenas Meu Código habilitado, o depurador nem tentará carregar símbolos para DLLs otimizadas. Localizar símbolos pode levar muito tempo.
Limitações da opção 'Suprimir otimização JIT'
Há duas situações em que ativar essa opção NÃO funcionará:
Em situações em que você está anexando o depurador a um processo já em execução, essa opção não terá efeito sobre os módulos que já estavam carregados no momento em que o depurador foi anexado.
Essa opção não tem efeito em DLLs que foram compiladas previamente (ou ngen’ed) no código nativo. No entanto, você pode desabilitar o uso de código pré-compilado iniciando o processo com a variável de ambiente 'COMPlus_ReadyToRun' definida como '0'. Isso instruirá o runtime do .NET Core a desabilitar o uso de imagens pré-compiladas, forçando o runtime a compilar código da estrutura JIT.
Se você estiver direcionando o .NET Framework, adicione a variável de ambiente 'COMPlus_ZapDisable' e defina-a como '1'.
Defina "COMPlus_ReadyToRun": "0"
adicionando-o a cada perfil no arquivo Properties\launchSettings.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"
}
}
}