Compartilhar via


Otimização e depuração JIT

Se você estiver tentando debugar o código, será mais fácil quando esse código não estiver otimizado. Quando o código é otimizado, o compilador e o runtime 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 poderão informar o valor das variáveis locais, e a execução de código e os pontos de interrupção podem não funcionar como você espera.

Observação

Para obter mais informações sobre a depuração do 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 build Release cria código otimizado e a de Debug não. A Optimize propriedade MSBuild controla se o compilador é instruído a otimizar o código.

No ecossistema do .NET, o código é transformado de origem para instruções de 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 .dll arquivos. 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ções JIT ao carregar o módulo (gerenciado somente)'

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 compila o código MSIL em código da CPU, as otimizações permanecerão habilitadas. Se a opção for verificada, o depurador solicitará que as otimizações sejam desabilitadas.

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

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 na carga do módulo (somente gerenciado) na caixa de diálogo Ferramentas>Opções, na seção Geral>Depuração:

Suprimir a otimização JIT

Quando você deve verificar a opção "Suprimir otimização JIT"?

Verifique essa opção quando você baixou as DLLs de outra origem, 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 diminui significativamente a depuração. Há duas razões para a desaceleração:

  • O código otimizado é executado mais rapidamente. Se você estiver desativando otimizações em muitos trechos de código, o impacto no desempenho poderá acumular.
  • Se você tiver o Just My Code 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á dois cenários em que habilitar 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 sobre os módulos já carregados no momento em que o depurador estiver anexado.
  • Essa opção não tem nenhum efeito sobre DLLs pré-compilados (ou ngen'ed) para 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'. Essa abordagem informa ao tempo de execução do .NET Core para desabilitar o uso de imagens pré-compiladas, o que força o tempo de execução a realizar a compilação Just-In-Time (JIT) do código do framework.

    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 a cada perfil no arquivo 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"
    }
  }
}