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


Устранение рисков. Новый 64-разрядный JIT-компилятор

Начиная с .NET Framework 4.6, среда выполнения включает в себя новый 64-разрядный JIT-компилятор. Это изменение не влияет на компиляцию с помощью 32-разрядного JIT-компилятора.

Непредвиденное поведение или исключения

В некоторых случаях компиляция с помощью нового 64-разрядного JIT-компилятора приводит к исключению среды выполнения или к поведению, которое не наблюдается при выполнении кода, скомпилированного старым 64-разрядным JIT-компилятором. Известные различия включают в себя следующее.

Внимание

Все эти известные проблемы устранены в новом 64-разрядном компиляторе на платформе .NET Framework 4.6.2. Большинство проблем было также устранено в выпусках обновлений платформы .NET Framework 4.6 и 4.6.1, включенных в состав обновления Windows. Эти проблемы можно устранить, обеспечив актуальность используемой версии Windows или обновив платформу до версии .NET Framework 4.6.2.

  • При определенных условиях операция распаковки может вызывать исключение NullReferenceException в сборках выпусков с включенной оптимизацией.

  • В некоторых случаях выполнение рабочего кода в большом теле метода может вызывать исключение StackOverflowException.

  • При определенных условиях в сборках выпусков передаваемые методу структуры обрабатываются как ссылочные типы, а не типы значений. Одним из проявлений этой проблемы является отображение отдельных элементов коллекции в непредвиденном порядке.

  • При определенных условиях сравнение значений UInt16 с установленным старшим битом выполняется неверно, если включена оптимизация.

  • При определенных условиях, особенно при инициализации значений массивов, инициализация памяти инструкцией OpCodes.Initblk IL может инициализировать память неправильным значением. Это может привести либо к необработанному исключению, либо к неправильным выходным данным.

  • В некоторых редких случаях условная поразрядная проверка может возвращать неверное значение типа Boolean или вызывать исключение, если включены оптимизации компилятора.

  • При определенных условиях, если инструкция if используется для проверки условия перед входом в блок try и на выходе из блока try, и такое же условие вычисляется в блоке catch или finally, новый 64-разрядный JIT-компилятор удаляет условие if из блока catch или finally при оптимизации кода. В результате код внутри инструкции if в блоке catch или finally выполняется безусловно.

Устранение известных проблем

При возникновении перечисленных выше проблем их можно решить, выполнив одно из следующих действий.

  • Обновление до .NET Framework 4.6.2. Новый 64-разрядный компилятор, входящий в состав .NET Framework 4.6.2, устраняет все эти известные проблемы.

  • Обновление Windows до актуального состояния при запуске Центра обновления Windows. Обновления служб до .NET Framework 4.6 и 4.6.1 решают все эти проблемы, кроме исключения NullReferenceException при распаковке-преобразовании.

  • Компиляция с помощью старого 64-разрядного JIT-компилятора. Дополнительные сведения о том, как это сделать, см. в разделе Устранение других проблем.

Устранение других проблем

При возникновении любых других различий в поведении между кодом, скомпилированным с помощью старого и нового 64-разрядных JIT-компиляторов, или между отладочной и окончательной версиями приложения, которые обе скомпилированы новым 64-разрядным JIT-компилятором, можно выполнить следующие действия для компиляции приложения с помощью старого 64-разрядного JIT-компилятора.

  • На основе каждого приложения можно добавить <элемент useLegacyJit> в файл конфигурации приложения. Следующее действие отключает компиляцию с помощью нового 64-разрядного JIT-компилятора и вместо этого использует устаревший 64-разрядный JIT-компилятор.

    <?xml version ="1.0"?>  
    <configuration>  
        <runtime>  
           <useLegacyJit enabled="1" />  
        </runtime>  
    </configuration>  
    
  • Для каждого отдельного пользователя можно добавить значение REG_DWORD с именем useLegacyJit в раздел реестра HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework. Значение 1 включает устаревший 64-разрядный JIT-компилятор; значение 0 отключает его и включает новый 64-разрядный JIT-компилятор.

  • Для каждого отдельного компьютера можно добавить значение REG_DWORD с именем useLegacyJit в раздел реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework. Значение 1 включает устаревший 64-разрядный JIT-компилятор; значение 0 отключает его и включает новый 64-разрядный JIT-компилятор.

Можно также сообщить нам об обнаруженной проблеме, обратившись в службу Microsoft Connect.

См. также