관리되는 실행 프로세스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.

    컴파일을 통해 소스 코드가 MSIL(Microsoft Intermediate Language)로 변환되고 필요한 메타데이터가 생성됩니다.Compiling translates your source code into Microsoft intermediate language (MSIL) and generates the required metadata.

  3. MSIL을 네이티브 코드로 컴파일.Compiling MSIL to native code.

    실행 시간에 JIT(Just-In-Time) 컴파일러는 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(공용 언어 런타임)에서 제공되는 이점을 얻으려면 런타임을 대상으로 지정하는 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.

CLR은 다국어 실행 환경이므로 런타임은 다양한 데이터 형식과 언어 기능을 지원합니다.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. 다른 언어로 작성된 구성 요소가 사용자의 구성 요소를 완전히 사용할 수 있어야 하면 사용자 구성 요소의 내보낸 형식은 CLS( Language Independence and Language-Independent Components )에 포함된 언어 기능만 노출해야 합니다.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

관리 코드를 컴파일하는 경우 컴파일러는 소스 코드를 네이티브 코드로 효율적으로 변환될 수 있는 CPU 독립적인 명령 집합인 MSIL(Microsoft Intermediate Language)로 변환합니다.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에는 개체에 대한 메서드를 로드, 저장, 초기화, 호출하는 명령과 산술 및 논리 연산, 제어 흐름, 직접 메모리 액세스, 예외 처리 및 기타 작업에 대한 명령이 포함됩니다.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. 코드를 실행하기 전에 보통 JIT(Just-In-Time) 컴파일러를 통해 MSIL을 CPU 특정 코드로 변환해야 합니다.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(공용 개체 파일 형식)에 기반을 두고 이를 확장하는 PE(이식 가능한 실행) 파일에 포함됩니다.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

MSIL(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는 이 변환을 수행하는 두 가지 방법을 제공합니다.The .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 컴파일러를 제공하므로 개발자는 다양한 컴퓨터 아키텍처를 가진 여러 가지 컴퓨터에서 JIT로 컴파일되고 실행될 수 있는 MSIL 어셈블리 집합을 빌드할 수 있습니다.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. 생성된 코드를 여러 애플리케이션 호출에서 또는 어셈블리 집합을 공유하는 여러 프로세스에서 공유할 수 있도록 공용 언어 런타임은 사전 컴파일 모드를 지원합니다.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. 이 사전 컴파일 모드에서는 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의 작업은 다음 세 가지 방법에서 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.

  • 한 번에 한 메서드가 아니라 한 번에 전체 어셈블리를 컴파일합니다.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 코드는 확인 프로세스를 통과해야 합니다.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. 보안 정책에 따라 형식 안전 코드가 필요하지만 코드가 확인을 통과하지 못하면 코드가 실행될 때 예외가 throw 됩니다.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 XPWindows 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