다음을 통해 공유


완화: 새로운 64비트 JIT 컴파일러

.NET Framework 4.6부터 런타임에는 Just-In-Time 컴파일을 위한 새로운 64비트 JIT 컴파일러가 포함됩니다. 이 변경 내용은 32비트 JIT 컴파일러를 사용한 컴파일에는 영향을 주지 않습니다.

예기치 않은 동작 또는 예외

경우에 따라 새 64비트 JIT 컴파일러를 사용하여 컴파일하면 런타임 예외가 발생하거나 이전 64비트 JIT 컴파일러에서 컴파일된 코드를 실행할 때 관찰되지 않는 동작이 발생합니다. 알려진 차이점은 다음과 같습니다.

중요합니다

이러한 알려진 모든 문제는 .NET Framework 4.6.2와 함께 릴리스된 새로운 64비트 컴파일러에서 해결되었습니다. 대부분은 Windows 업데이트에 포함된 .NET Framework 4.6 및 4.6.1의 서비스 릴리스에서도 해결되었습니다. Windows 버전이 최신 상태인지 확인하거나 .NET Framework 4.6.2로 업그레이드하여 이러한 문제를 제거할 수 있습니다.

  • 특정 상황에서 최적화가 설정된 릴리스 빌드에서 Unboxing 작업으로 인해 NullReferenceException이 throw될 수 있습니다.

  • 일부 경우에는 큰 메서드 본문의 프로덕션 코드가 실행될 때 StackOverflowException이 throw될 수 있습니다.

  • 특정 조건에서 메서드에 전달된 구조체는 릴리스 빌드의 값 형식이 아닌 참조 형식으로 처리됩니다. 이 문제의 징후 중 하나는 컬렉션의 개별 항목이 예기치 않은 순서로 표시되는 것입니다.

  • 특정 상황에서 최적화가 사용되도록 설정되어 있을 경우 UInt16 값을 높은 비트의 집합과 비교하면 결과가 잘못됩니다.

  • 배열 값을 초기화할 때와 같은 특정 상황에서 OpCodes.Initblk IL 명령에 따라 메모리가 초기화되면 잘못된 값이 사용될 수 있습니다. 이로 인해 처리되지 않은 예외 또는 잘못된 출력이 발생할 수 있습니다.

  • 드물게 특정한 상황에서 컴파일러 최적화가 사용되도록 설정되면 조건부 비트 테스트가 잘못된 Boolean 값을 반환하거나 예외를 throw할 수 있습니다.

  • 특정 상황에서 if 블록을 시작하기 전에 try 문을 사용해서 조건을 테스트한 후에 try 블록을 종료하고 catch 또는 finally 블록에서 동일한 조건을 평가하면 새로운 64비트 JIT 컴파일러는 코드를 최적화할 때 if 또는 catch 블록에서 finally 조건을 제거합니다. 결과적으로 if 또는 catch 블록에서 finally 문 내의 코드가 무조건적으로 실행됩니다.

알려진 문제 해결

위에 나열된 문제가 발생하는 경우 다음 중 하나를 수행하여 해결할 수 있습니다.

  • .NET Framework 4.6.2로 업그레이드합니다. .NET Framework 4.6.2에 포함된 새로운 64비트 컴파일러는 이러한 각각의 알려진 문제를 해결합니다.

  • Windows 업데이트를 실행하여 사용 중인 Windows 버전을 최신 상태로 유지합니다. .NET Framework 4.6 및 4.6.1에 대한 서비스 업데이트는 unboxing 작업의 NullReferenceException을 제외하고 이러한 각 문제를 해결합니다.

  • 이전 64비트 JIT 컴파일러를 사용하여 컴파일합니다. 방법에 대한 자세한 내용은 기타 문제 완화 섹션을 참조하세요.

기타 문제 해결

이전 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에 버그를 보고하여 문제를 알릴 수도 있습니다.

참고하십시오