티스토리 뷰

관리 코드(Managed Code)와 비관리 코드(Unmanaged Code)

이 글에서는 .NET 환경에서의 Managed Code와 Managed Code 이전의 Unmanaged Code에 대해서 알아보도록 하겠습니다.


Managed Code는 Visual Studio 2003 버전이 발표되면서 Microsoft에서 만들어낸 개념입니다. 일반적으로 .NET Framework 환경에서의 C#, VB.NET 환경에서 만든 코드는 모두 Managed Code입니다. 그리고 이 개념이 나오기 이전의 코드들은 Unmanaged Code라 보시면 됩니다.


C++은 기본적으로 Unmanaged Code라서 이 개념이 발표되었을 때 많은 혼란을 야기했다고 하네요. 하지만 이개념이 발표된 지 약 10년 정도 지났으니 많은 분들이 충분히 이해를 하고 있다고 생각이 듭니다.


1) 관리 코드(Managed Code)


Managed Code란 VB .NET 혹은 C# 컴파일러가 생성한 코드를 의미합니다. 컴파일러를 통해서 컴파일 된 Managed Code는 컴퓨터에서 바로 실행할 수 없는 중간언어(Intermediate Language, IL)입니다. 이 IL은 CLR(Common Language Runtime) 기반에서 실행이되는데, 이 Runtime은 IL이 정상인지를 먼저 파악을 하고, Runtime시 사용을 합니다. IL을 MSIL이라 부르기도 합니다. 


아래의 그림처럼 각 .NET 프레임워크 언어로 개발된 소스 코드는 컴파일러를 통해서 IL을 생성을 합니다. IL은 CLI(Common Language Infrastucture)에서 CIL(Common Intermediate Language)라 불리는 중간 언어로 컴파일을 하고, 이 CIL은 CLR(Common Language Runtime)을 통해서 머신 코드로 컴파일이 되어 실행이 되게 됩니다. 


Managed Code는 CLR기반에서 실행이 되는데, 이 런타임은 코드를 실행시키는 다양한 방법을 제공합니다. CLR은 먼저 IL 파일이 정상적인지 판단을 하고, Runtime에 사용되는 메소드를 호출합니다. 이를 Just In Time이라 부릅니다. 


Just In Time은 지속적으로 보안, 메모리 관리, 쓰레드와 같은 부분은 Runtime시에 지속적으로 관리를 합니다. VB .NET과 C#은 Managed Code만 생성이 가능합니다. 하지만 VC++은 Managed Code와 Unmanaged Code를 둘 다 만들 수 있습니다. 




이러한 구조를 통해서 .NET Framework 기반의 언어는 다른 플랫폼(다른 CPU, OS, 32-64bit)에서도 .NET Framework만 설치가 되어 있다면 문제없이 실행을 할 수 있습니다. 확장성이라는 장점을 가지는 반면 이전의 C, C++ 코드보다 많은 단계를 거쳐 실행이 되기 때문에 속도에 대한 단점을 가지고 있습니다. 


IL은 어셈블리라 불리는 파일에 저장이 되는데, 어셈블리에는 메타데이터라는 녀석과 같이 저장이 됩니다. 메타데이터에는 클래스, 메소드, 에트리뷰트등의 정보도 같이 포함이 되어있습니다. 어셈블리의 구조는 아래와 같습니다. 



2) 비관리 코드(Unmanaged Code)


Unmanaged Code는 Visual Studio .NET 2002가 릴리즈 되기 이전의 코드를 말하는데, 이는 VB 6.0, VC++ 6.0등에서 사용된 코드입니다. Unmanaged Code는 코드가 바로 Machine Code로 컴파일되고, 컴파일한 Machine과 동일한 칩등을 사용하는 환경에서만 실행이 가능합니다. Unmanaged Code는 보안, 메모리 관리등에 대해서 컨트롤 하지 않습니다. 



VC++에서 MFC, ATL, Win32 프로젝트를 생성하면 VC++을 Unmanaged Code로 컴파일이 됩니다. C++에서도 Managed Code로 프로그램을 작성하면 EXE파일과 함께 어셈블리가 생성이되고, Unmanaged Code로 작성을 하면 Native Code형태의 EXE 파일이 생성이 됩니다. 


Unmanaged Code는 Managed Code와는 달리 IL과 같은 중간언어를 만들지 않고, 컴파일 이후 실행이 바로 되는 머신 코드를 만들어 냅니다. 이는 속도에 대한 장점을 가지지만, 확장성의 한계를 가지게 됩니다.


3) Native Code


Native Code는 특정 프로세서에서 실행을 하기 위해 컴파일된 언어를 말합니다. 만약 다른 프로세서 기반에서 똑 같은 코드를 실행하고자 한다면 소스코드는 이 환경에 맞게 컴파일이 되어야 합니다. Native Code를 Unmanaged Code와 동일한 개념으로 사용하는 사람들이 많은데, 이는 조금 틀렸다고 볼 수 있습니다. 


.NET Framework를 기준으로 설명을 드리면, CLR은 MSIL이라 불리는 중간언어 코드를 특정 프로세서에서 실행할 수 있는 Native 코드로 변환을 해야 하기 때문입니다. 


Microsoft 에서 설명하고 있는 .NET Framework 언어의 실행과정은 다음과 같습니다. 2,3번 과정을 통해서 MSIL이 Native 코드로 변경되는 것을 확인할 수 있습니다.


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. Compiling your code to Microsoft intermediate language (MSIL).

Compiling translates your source code into MSIL and generates the required metadata.


3. Compiling MSIL to native code.

At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. 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. Executing your code.

The common language runtime provides the infrastructure that enables execution to take place as well as a variety of services that can be used during execution.


그럼 지금까지 Managed 코드와 Unmanaged 코드에 대해서 알아보았습니다.


이글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.



댓글