Поделиться через


Оптимизация JIT и отладка

Если вы пытаетесь отладить код, проще, если этот код не оптимизирован. При оптимизации кода компилятор и среда выполнения вносят изменения в создаваемый код ЦП, чтобы он выполнялся быстрее, но имеет менее прямое сопоставление с исходным кодом. Если сопоставление менее прямое, отладчики часто не могут сообщить вам значение локальных переменных, а пошаговое выполнение кода и точки останова могут не работать так, как вы ожидаете.

Замечание

Дополнительные сведения об отладке JIT (JIT-In-Time) см. в разделе Отладка с помощью JIT-In-Time отладчика в Visual Studio.

Как работают оптимизации в .NET

Обычно конфигурация сборки релиза создает оптимизированный код, а конфигурация сборки отладки этого не делает. Свойство Optimize MSBuild определяет, будет ли компилятор оптимизировать код.

В экосистеме .NET код преобразуется из источника в инструкции ЦП в двухфакторном процессе: сначала компилятор C# преобразует текст, который вы вводите в промежуточную двоичную форму MSIL, и записывает MSIL в .dll файлы. Позже среда выполнения .NET преобразует этот MSIL в инструкции ЦП. Оба шага могут оптимизироваться до некоторой степени, но второй шаг, выполняемый средой выполнения .NET, выполняет более значительные оптимизации.

Параметр "Подавление оптимизации JIT во время загрузки модуля (только для управляемого кода)"

Отладчик предоставляет параметр, который управляет тем, что происходит, когда библиотека DLL, скомпилированная с включенными оптимизацией, загружается внутри целевого процесса. Если этот параметр снят (состояние по умолчанию), то когда среда выполнения .NET компилирует код MSIL в код ЦП, он оставляет включенные оптимизации. Если установлен флажок, отладчик запрашивает отключение оптимизации.

Вы можете настроить параметр "Отключить оптимизацию JIT при загрузке модуля (только для управляемых)" в области Инструменты>Параметры в разделе Все настройки>Общие>Отладка:

Скриншот параметра отключения JIT-оптимизации при загрузке модуля.

Вы можете настроить параметр "Отключить оптимизацию JIT" для загрузки модуля (только для управляемого) в диалоговом окне"Параметры>" в разделе "Общая>отладка".

Подавление JIT-оптимизации

Когда следует проверить параметр "Подавление оптимизации JIT"?

Проверьте этот параметр, когда вы скачали библиотеки DLL из другого источника, например, пакета NuGet, и хотите отладить код в DLL. Чтобы подавление работало, необходимо также найти файл символа (.pdb) для этой библиотеки DLL.

Если вы заинтересованы только в отладке кода, который вы создаете локально, рекомендуется оставить этот параметр без флажка, так как в некоторых случаях включение этого параметра значительно замедляет отладку. Существует две причины замедления:

  • Оптимизированный код выполняется быстрее. Если вы отключаете оптимизацию для большого количества кода, влияние на производительность может существенно возрасти.
  • Если включен Just My Code, отладчик даже не пытается загружать символы для библиотек DLL, которые оптимизированы. Поиск символов может занять много времени.

Ограничения параметра "Подавление оптимизации JIT"

Существует два сценария, в которых включение этого параметра не работает:

  • Если подключить отладчик к уже запущенному процессу, этот параметр не влияет на модули, уже загруженные во время подключения отладчика.
  • Этот параметр не влияет на предварительно скомпилированные библиотеки DLL (или ngen'ed) в машинный код. Однако можно отключить использование предварительно скомпилированного кода, запуская процесс с переменной среды "COMPlus_ReadyToRun", для которой задано значение "0". Этот подход указывает среде выполнения .NET Core отключить использование предварительно скомпилированных образов, что заставляет среду выполнения выполнять компиляцию кода платформы JIT.

    Если вы нацелены на .NET Framework, добавьте переменную среды "COMPlus_ZapDisable" и задайте для нее значение "1".

Задайте "COMPlus_ReadyToRun": "0", добавив его в каждый профиль в разделе Свойства\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"
    }
  }
}