Устранение рисков. Новый 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.