Partilhar via


Otimização e depuração JIT

Se você estiver tentando depurar o código, é mais fácil quando esse código NÃO está otimizado. Quando o código é otimizado, o compilador e o tempo de execução fazem alterações no código da 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 conseguem informar o valor das variáveis locais, e a execução do código passo a passo e os pontos de interrupção podem não funcionar conforme o esperado.

Observação

Para obter mais informações sobre depuração JIT (Just-In-Time), consulte Depurar usando o depurador Just-In-Time no Visual Studio.

Como as otimizações funcionam no .NET

Normalmente, a configuração de construção de Release cria código otimizado e a configuração de construção de Debug não. A Optimize propriedade MSBuild controla se o compilador é instruído a otimizar o código.

No ecossistema .NET, o código é transformado do código-fonte para as instruções da CPU em um processo de duas etapas: primeiro, o compilador C# converte o texto digitado em uma forma binária intermediária chamada MSIL e grava o MSIL em arquivos .dll. Mais tarde, o .NET Runtime converte este MSIL para instruções de CPU. Ambas as etapas podem otimizar até certo ponto, mas a segunda etapa executada pelo .NET Runtime executa as otimizações mais significativas.

A opção 'Suprimir otimização JIT na carga 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 .NET Runtime compilar o código MSIL no código da CPU, ele deixará as otimizações habilitadas. Se a opção estiver marcada, o depurador solicitará que as otimizações sejam desativadas.

Você pode configurar a opção Suprimir otimização JIT na carga do módulo (somente gerenciado) no painel Ferramentas>, Opções, na seção Todas as Configurações>, Geral>, Depuração:

Captura de tela da opção Suprimir otimização JIT na depuração de carga do módulo.

Você pode configurar a opção Suprimir otimização JIT no carregamento do módulo (apenas gerido) na caixa de diálogo Ferramentas>Opções, na seção Geral>Depuração:

Suprimir a otimização do JIT

Quando você deve marcar a opção 'Suprimir otimização JIT'?

Marque essa opção quando você baixou as DLLs de outra fonte, como um pacote NuGet, e deseja depurar o código nessa DLL. Para que a supressão funcione, você também deve encontrar o arquivo de símbolo (.pdb) para esta 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, ativar essa opção retarda significativamente a depuração. Há duas razões para o abrandamento:

  • O código otimizado é executado mais rapidamente. Se você estiver desativando otimizações para muitos códigos, o impacto no desempenho pode aumentar.
  • Se você tiver Just My Code habilitado, o depurador nem mesmo tentará carregar símbolos para DLLs otimizadas. Encontrar símbolos pode levar muito tempo.

Limitações da opção 'Suprimir otimização JIT'

Há dois cenários em que ativar essa opção NÃO funciona:

  • Se você anexar o depurador a um processo já em execução, essa opção não terá efeito nos módulos já carregados no momento em que o depurador for anexado.
  • Esta opção não tem efeito sobre DLLs pré-compiladas (ou geradas por ngen) para código nativo. No entanto, você pode desativar o uso de código pré-compilado iniciando o processo com a variável de ambiente 'COMPlus_ReadyToRun' definida como '0'. Essa abordagem informa ao runtime do .NET Core para desabilitar o uso de imagens pré-compiladas, obrigando o runtime a compilar o código JIT da framework.

    Se estiveres a apontar para o .NET Framework, adiciona a variável de ambiente 'COMPlus_ZapDisable' e define-a como '1'.

Defina "COMPlus_ReadyToRun": "0" adicionando-o a cada perfil no ficheiro Propriedades\launchSettings.js:

{
  "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"
    }
  }
}