7

Q1) なぜ C# は最初に IL にコンパイルされ、次に実行時に JIT にコンパイルされ、仮想マシン上で実行されるのですか (?)。それとも、ネイティブのマシンコードに準拠した JIT ですか?

Q2) 2 番目が正しい場合 (ネイティブ マシン コードに準拠した JIT)、コードが実行される .NET サンドボックスはどこにありますか?

Q3) また、そもそもコードを IL にコンパイルする理由を教えてください。常にネイティブ マシン コードにコンパイルしないのはなぜですか? ngenと呼ばれるMSのツールがありますが、なぜそれがオプションなのですか?

4

6 に答える 6

12

ILは、プロセスの実行時にネイティブマシンコードにコンパイルされてJITされます(JIT = Just In Time)。

仮想マシンレイヤーを使用すると、プラットフォーム間で.NETが一貫した方法で動作できるようになります(たとえば、32ビットマシンと64ビットマシンのどちらで実行しているかに関係なく、intは常に32ビットですが、C++の場合はそうではありません。 )。

JITコンパイルを使用すると、実行時にコードに合わせて最適化を動的に調整できます(たとえば、頻繁に呼び出されるコードのビットにさらに積極的な最適化を適用したり、SSE2などの特定のマシンで利用可能なハードウェア命令を利用したりできます)。静的コンパイラ。

于 2010-02-05T15:46:57.600 に答える
3

A1) JIT はネイティブ マシン コードにコンパイルします。

A2) .net にはサンドボックスという用語はありません。代わりに AppDomains があります。そして、それらは CLR の一部として (つまり、実行可能なプロセスの一部として) 実行されます。

A3) Jeffrey Richter による NGen の欠点:

  • NGen 化されたファイルが同期しなくなる可能性があります。CLR は、NGen 化されたファイルを読み込むときに、以前にコンパイルされたコードと現在の実行環境に関する多くの特性を比較します。いずれかの特性が一致しない場合、NGen 化されたファイルは使用できず、代わりに通常の JIT コンパイラ プロセスが使用されます。

  • 読み込み時のパフォーマンスが低い (リベース/バインド)。アセンブリ ファイルは標準の Windows PE ファイルであり、それぞれに優先ベース アドレスが含まれています。多くの Windows 開発者は、ベース アドレスとリベースに関する問題に精通しています。コードを JIT コンパイルする場合、実行時に正しいメモリ アドレス参照が計算されるため、これらの問題は問題になりません。

  • 劣った実行時間パフォーマンス。コードをコンパイルするとき、NGen は JIT コンパイラーほど多くの実行環境を想定することはできません。これにより、NGen.exe が劣悪なコードを生成します。たとえば、NGen は特定の CPU 命令の使用を最適化しません。静的フィールドの実際のアドレスは実行時までわからないため、静的フィールドへのアクセスに間接性が追加されます。NGen は、コードが実行される順序や、クラス コンストラクターが既に呼び出されているかどうかがわからないため、どこにでもクラス コンストラクターを呼び出すコードを挿入します。

于 2010-02-05T15:55:00.280 に答える
1

NGENを使用して、.NET アセンブリのネイティブ バージョンを作成できます。これを行うことは、JIT が実行時にこれを行う必要がないことを意味します。

.NET はまず IL にコンパイルされ、次にネイティブにコンパイルされます。JIT は、コードが実行されている現在の CPU に合わせて IL コードを最適化するように設計されているためです。

.NET コードは、互換性のために IL にコンパイルされます。C#、VB.NET などを使用してコードを作成できるため、ネイティブ コードにコンパイルするには、JIT に共通命令セット (IL) が必要です。JIT が言語を認識する必要がある場合、新しい .NET 言語がリリースされたときに JIT を更新する必要があります。

サンドボックスの質問についてはよくわかりませんが、.NET アプリは 3 つのアプリケーション ドメインで実行されると推測されます。1 つのドメインには .NET ランタイム (mscorlib、system.dll など) が含まれ、別のドメインには .NET コードが含まれています。http://my.safaribooksonline.com/9780321584090をご覧ください

于 2010-02-05T15:50:56.287 に答える
0

1. C#は、他の.NET言語とプラットフォームを共有するためCIL(またはIL)にコンパイルされます(そのため、DLLをC#で記述し、VB.NETまたはF#で手間をかけずに使用できます)。次に、CLRはコードをネイティブマシンコードにJITコンパイルします。

.NETは、複数のプラットフォーム(*NIXおよびOSX上のMono)でも実行できます。C#をネイティブコードにコンパイルした場合、これはそれほど簡単ではありません。

2.サンドボックスはありません。

3.#1の答えでカバーされています

于 2010-02-05T15:48:08.847 に答える
0

A1)このように、プラットフォームに依存せず(Windows、Linux、Mac)、現在のハードウェアに特定の最適化を使用することもできます。JITをコンパイルすると、マシンコードになります。

A2)フレームワーク全体(.NET Framework)はすべてサンドボックスであるため、アプリを介して行う可能性のあるすべての呼び出しは、.NETFrameworkサンドボックスを経由します。

A3)回答1と同様に、.NETバイナリをさまざまなプラットフォームで動作させ、クライアントマシンで特定の最適化をオンザフライで実行できます。

于 2010-02-05T15:49:41.413 に答える
0

コンパイルされた .Net コードは、Java のオブジェクト コードとまったく同じ方法で中間言語である IL になります。はい、 NGenツールを使用してネイティブ マシン コードを生成することは可能です。NGen は、生成されたネイティブ イメージをマシンにバインドするため、ngen 化されたバイナリを別のシステムにコピーしても、期待どおりの結果が得られません。中間コードにコンパイルすることで、C++ のような静的に型付けされた言語では (簡単に) 行うことができない実行時の決定が可能になります。また、コードがコード内で記述的になるため、さまざまなハードウェア アーキテクチャでコードを機能させることも可能になります。 32 ビット システムまたは 64 ビット システムでのみ動作し、両方では動作しないマシン固有のコードとは対照的に、ビット (32 または 64 など) にとらわれない方法で発生する必要があることの意図も記述していると感じます。

また、NGen はバイナリをシステムにバインドするため、オプションです。動的に型付けされた言語の柔軟性を備えたコンパイル済みマシン コードのパフォーマンスが必要であり、バイナリが次の場所に移動しないことがわかっている場合に役立ちます。バインドされていないシステム。

于 2010-02-05T15:52:01.207 に答える