マネージド実行プロセスManaged Execution Process

マネージド実行プロセスで実行される主な手順を次に示します。詳細については、後で説明します。The managed execution process includes the following steps, which are discussed in detail later in this topic:

  1. コンパイラを選択しますChoosing a compiler.

    共通言語ランタイムが提供する機能を利用するためには、共通言語ランタイムに対応した言語コンパイラを使用する必要があります。To obtain the benefits provided by the common language runtime, you must use one or more language compilers that target the runtime.

  2. コードを MSIL にコンパイルしますCompiling your code to MSIL.

    コンパイルを実行するとソース コードが Microsoft Intermediate Language (MSIL) に変換され、必要なメタデータが生成されます。Compiling translates your source code into Microsoft intermediate language (MSIL) and generates the required metadata.

  3. MSIL からネイティブ コードにコンパイルしますCompiling MSIL to native code.

    実行時に、ジャスト イン タイム (JIT) コンパイラによって MSIL がネイティブ コードに変換されます。At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. このコンパイルの実行時に、コードは検証プロセスで確認される必要があります。この検証プロセスでは、MSIL とメタデータが調べられ、コードがタイプ セーフかどうかが確認されます。During this compilation, code must pass a verification process that examines the MSIL and metadata to find out whether the code can be determined to be type safe.

  4. コードを実行しますRunning code.

    共通言語ランタイムは、実行を可能にするインフラストラクチャと実行時に使用できるサービスを提供します。The common language runtime provides the infrastructure that enables execution to take place and services that can be used during execution.

コンパイラを選択しますChoosing a Compiler

共通言語ランタイム (CLR: Common Language Runtime) によって提供される機能を活用するには、Visual Basic、C#、Visual C++、F# などのランタイムに対応した言語コンパイラか、Eiffel、Perl、COBOL などのサードパーティのコンパイラを使用する必要があります。To obtain the benefits provided by the common language runtime (CLR), you must use one or more language compilers that target the runtime, such as Visual Basic, C#, Visual C++, F#, or one of many third-party compilers such as an Eiffel, Perl, or COBOL compiler.

共通言語ランタイムは多言語実行環境であるため、さまざまなデータ型と言語機能をサポートしています。Because it is a multilanguage execution environment, the runtime supports a wide variety of data types and language features. 使用する言語コンパイラによって、利用できる共通言語ランタイムの機能が決まり、その機能を使用してコードをデザインすることになります。The language compiler you use determines which runtime features are available, and you design your code using those features. 記述するコードの構文を決定するのは、共通言語ランタイムではなく、使用するコンパイラです。Your compiler, not the runtime, establishes the syntax your code must use. 作成したコンポーネントを他の言語で記述されたコンポーネントでも完全に使用できるようにするためには、そのコンポーネントからエクスポートされた型が、 Language Independence and Language-Independent Components (CLS) に規定されている言語機能だけを公開するようにする必要があります。If your component must be completely usable by components written in other languages, your component's exported types must expose only language features that are included in the Language Independence and Language-Independent Components (CLS). CLSCompliantAttribute 属性を使用することにより、コードを確実に CLS に準拠させることができます。You can use the CLSCompliantAttribute attribute to ensure that your code is CLS-compliant. 詳細については、「 Language Independence and Language-Independent Components」を参照してください。For more information, see Language Independence and Language-Independent Components.

ページのトップへBack to top

MSIL へのコンパイルCompiling to MSIL

マネージド コードへのコンパイル時に、コンパイラはソース コードを MSIL (Microsoft Intermediate Language) に変換します。MSIL は CPU に依存しない一連の命令で、効率的にネイティブ コードに変換できます。When compiling to managed code, the compiler translates your source code into Microsoft intermediate language (MSIL), which is a CPU-independent set of instructions that can be efficiently converted to native code. MSIL には、オブジェクトに対する読み込み、格納、初期化、および呼び出し用の命令の他に、算術演算と論理演算、制御フロー、DMA (Direct Memory Access)、例外処理、およびその他の操作のための命令も含まれています。MSIL includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations. コードを実行する前に、MSIL を CPU 固有のコードに変換する必要があります。通常、この変換は Just-In-Time (JIT) コンパイラによって行われます。Before code can be run, MSIL must be converted to CPU-specific code, usually by a just-in-time (JIT) compiler. 共通言語ランタイムはサポートするコンピューター アーキテクチャごとに JIT コンパイラを提供しているため、同じ MSIL セットを JIT コンパイルして、サポートされているすべてのアーキテクチャで実行できます。Because the common language runtime supplies one or more JIT compilers for each computer architecture it supports, the same set of MSIL can be JIT-compiled and run on any supported architecture.

コンパイラは、MSIL を生成するときにメタデータも生成します。When a compiler produces MSIL, it also produces metadata. メタデータには、コード内の型について、それぞれの型の定義、型のメンバーのシグネチャ、コードが参照するメンバー、共通言語ランタイムが実行時に使用するその他のデータなどが記述されています。Metadata describes the types in your code, including the definition of each type, the signatures of each type's members, the members that your code references, and other data that the runtime uses at execution time. MSIL とメタデータは、実行可能ファイルのファイル形式として使用されてきた従来の Microsoft PE と COFF (Common Object File Format) に基づき、それらを拡張した移植可能な実行可能 (PE: Portable Executable) ファイルに格納されます。The MSIL and metadata are contained in a portable executable (PE) file that is based on and that extends the published Microsoft PE and common object file format (COFF) used historically for executable content. MSIL、ネイティブ コード、およびメタデータを保存できるこのファイル形式を使用すると、オペレーティング システムが共通言語ランタイムのイメージを認識できるようになります。This file format, which accommodates MSIL or native code as well as metadata, enables the operating system to recognize common language runtime images. MSIL と共にメタデータがこのファイルに格納されるため、コードは自己記述型になります。つまり、タイプ ライブラリまたはインターフェイス定義言語 (IDL: Interface Definition Language) は必要ありません。The presence of metadata in the file together with MSIL enables your code to describe itself, which means that there is no need for type libraries or Interface Definition Language (IDL). 共通言語ランタイムは、実行時にこのファイルから必要に応じてメタデータを検出および抽出します。The runtime locates and extracts the metadata from the file as needed during execution.

ページのトップへBack to top

MSIL からネイティブ コードにコンパイルしますCompiling MSIL to Native Code

Microsoft Intermediate Language (MSIL) は、実行する前に、共通言語ランタイムに対して、対象コンピューターのアーキテクチャ用のネイティブ コードにコンパイルしておく必要があります。Before you can run Microsoft intermediate language (MSIL), it must be compiled against the common language runtime to native code for the target machine architecture. .NET Framework.NET Framework には、この変換を実行する 2 つの方法が用意されています。The .NET Framework.NET Framework provides two ways to perform this conversion:

JIT コンパイラによるコンパイルCompilation by the JIT Compiler

JIT コンパイルは、アプリケーション実行時に、アセンブリの内容が読み込まれて実行される際に、オン デマンドで MSIL をネイティブ コードに変換します。JIT compilation converts MSIL to native code on demand at application run time, when the contents of an assembly are loaded and executed. 共通言語ランタイムには、サポートされる CPU アーキテクチャごとに JIT コンパイラが用意されているため、開発者は MSIL アセンブリのセットを作成し、それを JIT でコンパイルして、異なるマシン アーキテクチャを持つさまざまなコンピューター上で実行できます。Because the common language runtime supplies a JIT compiler for each supported CPU architecture, developers can build a set of MSIL assemblies that can be JIT-compiled and run on different computers with different machine architectures. ただし、マネージド コードがプラットフォーム固有のネイティブ API またはプラットフォーム固有のクラス ライブラリを呼び出す場合、そのコードはそのオペレーティング システムでしか実行されません。However, if your managed code calls platform-specific native APIs or a platform-specific class library, it will run only on that operating system.

JIT コンパイルは、実行時に呼び出されることがないコードがある可能性を考慮しています。JIT compilation takes into account the possibility that some code might never be called during execution. つまり、PE ファイル内にあるすべての MSIL をネイディブ コードに変換するために時間とメモリを費やす代わりに、実行時に必要とされる MSIL を変換し、結果として生成されるネイティブ コードをメモリに保存することで、そのプロセスのコンテキスト内の後続の呼び出しがこれを利用できるようにします。Instead of using time and memory to convert all the MSIL in a PE file to native code, it converts the MSIL as needed during execution and stores the resulting native code in memory so that it is accessible for subsequent calls in the context of that process. 型が読み込まれて初期化されるとき、ローダーはスタブを作成し、その型の各メソッドにそれを結び付けます。The loader creates and attaches a stub to each method in a type when the type is loaded and initialized. メソッドが初めて呼び出されるとき、スタブは JIT コンパイラに制御を渡します。JIT コンパイラはそのメソッド用の MSIL をネイティブ コードに変換して、生成されたネイティブ コードを直接指すようスタブを変更します。When a method is called for the first time, the stub passes control to the JIT compiler, which converts the MSIL for that method into native code and modifies the stub to point directly to the generated native code. このため、JIT でコンパイルされたメソッドに対する後続の呼び出しでは、ネイティブ コードが直接実行されます。Therefore, subsequent calls to the JIT-compiled method go directly to the native code.

NGen.exe を使用したインストール時のコード生成Install-Time Code Generation Using NGen.exe

JIT コンパイラは、アセンブリの MSIL を、そのアセンブリで定義されている個々のメソッドが呼び出されるときにネイティブ コードに変換するため、実行時のパフォーマンスが低下します。Because the JIT compiler converts an assembly's MSIL to native code when individual methods defined in that assembly are called, it affects performance adversely at run time. ほとんどの場合、このパフォーマンスの低下は許容範囲内です。In most cases, that diminished performance is acceptable. より重要な点として、JIT コンパイラが生成したコードは、コンパイルを起動したプロセスにバインドされます。More importantly, the code generated by the JIT compiler is bound to the process that triggered the compilation. 複数のプロセスの間でこれを共有することはできません。It cannot be shared across multiple processes. 生成されたコードを、1 つのアプリケーションの複数の呼び出しの間で、または 1 つのアセンブリ セットを共有する複数のプロセスの間で共有できるようにするために、共通言語ランタイムは事前コンパイル モードをサポートします。To allow the generated code to be shared across multiple invocations of an application or across multiple processes that share a set of assemblies, the common language runtime supports an ahead-of-time compilation mode. この Ahead Of Time コンパイル モードでは、Ngen.exe (ネイティブ イメージ ジェネレーター) を使用して、JIT コンパイラと同様に MSIL アセンブリをネイティブ コードに変換します。This ahead-of-time compilation mode uses the Ngen.exe (Native Image Generator) to convert MSIL assemblies to native code much like the JIT compiler does. ただし、Ngen.exe の動作は、以下の 3 つの点で JIT コンパイラの動作と異なります。However, the operation of Ngen.exe differs from that of the JIT compiler in three ways:

  • MSIL からネイティブ コードへの変換を、アプリケーション実行中ではなく、実行前に行います。It performs the conversion from MSIL to native code before running the application instead of while the application is running.

  • メソッドを 1 つずつコンパイルするのではなく、アセンブリ全体を一度にコンパイルします。It compiles an entire assembly at a time, instead of one method at a time.

  • 生成したコードを、ディスク上のファイルとしてネイティブ イメージ キャッシュに保持します。It persists the generated code in the Native Image Cache as a file on disk.

コードの検証Code Verification

コード検証の省略を許可するセキュリティ ポリシーを管理者が設定していない限り、MSIL からネイティブ コードへのコンパイル時に、MSIL コードは検証プロセスを通過する必要があります。As part of its compilation to native code, the MSIL code must pass a verification process unless an administrator has established a security policy that allows the code to bypass verification. この検証プロセスでは、コードがタイプ セーフかどうかを確認するために、MSIL とメタデータが調べられます。タイプ セーフなコードとは、アクセス権限を与えられているメモリ位置だけにアクセスするコードを意味します。Verification examines MSIL and metadata to find out whether the code is type safe, which means that it accesses only the memory locations it is authorized to access. タイプ セーフは、オブジェクトを相互に分離するため、不注意や悪意による破損からオブジェクトを保護するために役立ちます。Type safety helps isolate objects from each other and helps protect them from inadvertent or malicious corruption. また、コードに対するセキュリティ制限が強制適用されることも保証されます。It also provides assurance that security restrictions on code can be reliably enforced.

共通言語ランタイムは、検証可能なタイプ セーフ コードが次の条件を満たすことを前提としています。The runtime relies on the fact that the following statements are true for code that is verifiably type safe:

  • 型への参照には参照される型との間に完全な互換性がある。A reference to a type is strictly compatible with the type being referenced.

  • 適切に定義された操作だけがオブジェクトに対して呼び出される。Only appropriately defined operations are invoked on an object.

  • ID が正しい。Identities are what they claim to be.

検証プロセスでは、MSIL コードが調べられ、適切に定義された型だけを使用してメモリ位置にアクセスしたりメソッドを呼び出したりするかどうかが確認されます。During the verification process, MSIL code is examined in an attempt to confirm that the code can access memory locations and call methods only through properly defined types. たとえば、オブジェクトのフィールドにアクセスするときにメモリ位置をオーバーランできるようなコードは許可されません。For example, code cannot allow an object's fields to be accessed in a manner that allows memory locations to be overrun. また、不正な MSIL があるとタイプ セーフ規則に違反する可能性があるため、MSIL が正しく生成されているかどうかも調べられます。Additionally, verification inspects code to determine whether the MSIL has been correctly generated, because incorrect MSIL can lead to a violation of the type safety rules. 検証プロセスは適切に定義されたタイプ セーフ コードのセットを許可します。許可されるコードはタイプ セーフなコードだけです。The verification process passes a well-defined set of type-safe code, and it passes only code that is type safe. ただし、タイプ セーフなコードの中にも、検証プロセスの制約事項のために検証を通過しないコードがあります。また、言語によっては、デザイン上、検証可能なタイプ セーフ コードが生成されない場合もあります。However, some type-safe code might not pass verification because of some limitations of the verification process, and some languages, by design, do not produce verifiably type-safe code. セキュリティ ポリシーがタイプ セーフなコードを必要とするにもかかわらず、コードが検証を通過しない場合には、そのコードの実行時に例外がスローされます。If type-safe code is required by the security policy but the code does not pass verification, an exception is thrown when the code is run.

ページのトップへBack to top

コードを実行しますRunning Code

共通言語ランタイムは、マネージド実行を可能にするインフラストラクチャと実行時に使用できるサービスを提供します。The common language runtime provides the infrastructure that enables managed execution to take place and services that can be used during execution. メソッドは、実行する前にプロセッサ固有のコードにコンパイルされている必要があります。Before a method can be run, it must be compiled to processor-specific code. 対応する MSIL が生成されているメソッドは、初めて呼び出されたときに JIT コンパイルされてから実行されます。Each method for which MSIL has been generated is JIT-compiled when it is called for the first time, and then run. 次にこのメソッドが実行されるときには、JIT コンパイル済みの既存のネイティブ コードが実行されます。The next time the method is run, the existing JIT-compiled native code is run. JIT コンパイルからコード実行までのプロセスは、実行が完了するまで繰り返されます。The process of JIT-compiling and then running the code is repeated until execution is complete.

実行時に、マネージド コードは、ガベージ コレクション、セキュリティ、アンマネージド コードとの相互運用性、言語間デバッグ サポート、強化された配置とバージョン管理のサポートなどのさまざまなサービスを利用できます。During execution, managed code receives services such as garbage collection, security, interoperability with unmanaged code, cross-language debugging support, and enhanced deployment and versioning support.

Microsoft Windows XPWindows XP および Windows VistaWindows Vistaでは、オペレーティング システム ローダーが COFF ヘッダー内のビットを調べることにより、マネージド モジュールをチェックします。In Microsoft Windows XPWindows XP and Windows VistaWindows Vista, the operating system loader checks for managed modules by examining a bit in the COFF header. 設定されたビットはマネージド モジュールを意味します。The bit being set denotes a managed module. ローダーがマネージド モジュールを検出すると、mscoree.dll が読み込まれます。マネージド モジュール イメージが読み込まれるときとアンロードされるときには、 _CorValidateImage および _CorImageUnloading がローダーに通知します。If the loader detects managed modules, it loads mscoree.dll, and _CorValidateImage and _CorImageUnloading notify the loader when the managed module images are loaded and unloaded. _CorValidateImage は、次のアクションを実行します。_CorValidateImage performs the following actions:

  1. コードが有効なマネージド コードであることを確認します。Ensures that the code is valid managed code.

  2. イメージのエントリ ポイントをランタイムのエントリ ポイントに変更します。Changes the entry point in the image to an entry point in the runtime.

64 ビット Windows では、 _CorValidateImage は、メモリ内のイメージを PE32 から PE32+ 形式に変換することによって変更します。On 64-bit Windows, _CorValidateImage modifies the image that is in memory by transforming it from PE32 to PE32+ format.

ページのトップへBack to top

関連項目See also