.NET Framework のネイティブ イメージが無効になる状況と考えられる影響について

こんにちは、Visual Studio サポート チームです。

.NET Framework のライブラリは中間言語 (MSIL) 形式のアセンブリとして提供されていますが、これらは事前にコンパイルされるか、アプリケーションの実行時に JIT コンパイルされて機械語に変換され、プログラムから利用されます。

今回は、Windows Update の適用などに伴い .NET Framework のネイティブ イメージが無効になり再作成が行われる動作と、考えられる影響などについてご案内します。

 

現象

Windows Update や .NET Framework の更新プログラムの適用後、.NET Framework を使用するアプリケーションやサービスの動作が遅くなる場合や、CPU 使用率が高騰する場合があります。

PowerShell など、 .NET Framework 上で動作するスクリプトをホストするプロセスも同様の事象が発生する場合があります。

なお、下記の KB で案内しているとおり、32 ビットの .NET Framework に比べて 64 ビットの .NET Framework のほうが JIT コンパイルが必要となることに伴う影響は大きい傾向があります。

64 ビットの .NET Framework アプリケーションの起動に時間がかかる
https://support.microsoft.com/ja-jp/help/2833666

 

また、この事象は一般的には一時的なものですが、何らかの理由で常に高い負荷の状態となっているコンピューターでは長期にわたり解消されないことがあります。

 

原因

Windows Update や .NET Framework の更新プログラムの適用でアセンブリが置き換わった場合、ネイティブ イメージとの不整合を避けるため、ネイティブ イメージは一旦無効な状態として扱われます。

このとき同時にネイティブ イメージの再作成がスケジュールされますが、実行はシステムのアイドル時に行われるため、再作成されるまでの間、アプリケーションの実行時は JIT コンパイルが必要となります。

この場合も、ネイティブ イメージでの動作と中間言語のアセンブリでの動作の間で、アプリケーションの実行結果に相違が生じることはありません。

ただし、JIT コンパイルの処理によって、アプリケーションの起動や実行が遅くなる場合や、プロセスの CPU 使用率やメモリ使用量が高くなる場合があります。

なお、Windows 10 および Windows Server 2016 では .NET Framework の更新プログラムは OS の更新プログラムとともにリリースされるため、OS の更新プログラムの適用時にもネイティブ イメージが無効となる可能性があります。

また、システムがアイドル状態とならないような常に高い負荷が続く状況ではネイティブ イメージの再作成が行われないため、自動的には JIT コンパイルが必要な状況が解消されません。

 

対処方法

通常この現象は一時的なもので、システムがアイドル状態になった後自動的にネイティブ イメージが再作成されるため、特別な対処は必要ないことがほとんどです。

ネイティブ イメージが自動的に再作成されることを待たず直ちに再作成が必要となる場合、もしくは常に高い負荷が続く状況などで自動的な再作成が期待できない場合は、明示的にネイティブ イメージの再作成を行ってください。

明示的にネイティブ イメージの再作成を行うには、.NET Framework に含まれる ngen.exe を以下の手順で実行します。

 

(1) 管理者権限でコマンド プロンプトを起動します。

(2) 下記の 2 つのコマンドを実行します。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe executeQueuedItems

C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe update

(3) 64 bit OS の場合は、続けて下記の 2 つのコマンドを実行します。

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe executeQueuedItems

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update

 

なお、上記コマンドの実行中はネイティブ イメージの生成のためシステムの負荷が高くなります。

実行が完了するまでの所要時間はインストールされているネイティブ イメージの状況に依存するため、あらかじめ検証可能な環境などで所要時間をご確認いただいた上で実施することをお勧めします。

 

参考情報 – ネイティブ イメージについて

.NET Framework 上で動作するアセンブリには、CPU が直接実行できる命令ではなく、.NET Framework が実行時 (JIT : Just-in-Time) にコンパイルして CPU 命令に変換するための中間言語が含まれています。

JIT コンパイルはアプリケーションの起動や実行のパフォーマンスに影響を与える可能性があるため、その対処として予め CPU が直接実行できる命令にコンパイルしておくことも可能です。

予めコンパイルされたファイルをネイティブ イメージと呼び、 C:\windows\assembly フォルダー配下の NativeImages_v4.0.30319_32 フォルダーなどに、***.ni.dll という名称で保存されています。

ネイティブ イメージの生成には長時間を要するため、更新プログラムの適用により無効となった場合も再作成は同時には行われず、更新プログラムの適用後に実行するようにスケジュールされます。

また、ネイティブ イメージの生成は CPU やメモリ、ディスク IO などのリソースを多く使用するため、実行中のアプリケーションやサービスの動作に影響を与えないよう、システムがアイドル状態のときに実行されます。

ネイティブ イメージの詳細につきましては下記のドキュメントをご確認ください。

Ngen.exe (ネイティブ イメージ ジェネレーター)
/ja-jp/dotnet/framework/tools/ngen-exe-native-image-generator