먼저 이 포스트는 C# and the .NET Platform Second Edition / Andrew Troelsen / Apress (C#과 닷넷 플랫폼(제 2판) / 장시형 역 / 사이텍 미디어) 이 책을 참고하여, 내용을 좀더 쉽게 이해하도록 설명하듣 정리한 포스트 입니다. 때문에 저작권적 문제가 있다면(발생 한다면) 언제든지 삭제가 될 수 있는 포스트임을 밝혀 드립니다. |
1. .NET 솔루션
- Win32 코드와의 완벽한 상호 운용성 : 기존 COM 바이너리와 새로 만드는 .NET 바이너리를 합칠 수 있다. 또한 PInvoke(Platform Invocation, 플랫폼 호출)을 이용, 관리 코드(Managed code)에서 Win32 API와 같은 C기반 함수를 호출할 수 있다. 1
- 기존 COM과 달리, .NET은 언어간 교차 상속, 교차 언어 예외 처리, 교차 언어 디버깅을 지원한다.
- 모든 .NET 언어가 공유하는 공용 런타임 엔진이 있다. 이 엔진은 각각의 .NET 지원 어어가 '이해할 수 있는' 명확히 정의된 형식(Type)들의 집합이다.
- 직접 API를 호출하는 번거로움을 줄여주며, .NET 지원 언어들에서 사용하기에 알맞은 객체 모델을 제공하는 기본 클래스 라이브러리.
- .NET은 바이너리 유닛(*.dll 등)을 시스템 레지스트리에 등록할 필요가 없다. 또한 .NET 런타임에서 'side-by-side'실행 이라는 접근법을 이용, 동일한 *.dll이 여러 버전으로 한 머신에서 충돌 없이 존재할 수 있도록 한다. 이로서 배포가 간편해 진다.
2. .NET 플랫폼의 구성 요소(CLR, CTS, CLS)
2.1 CLR : Common Language Runtime
Java에서 말하는 VM과 같은 거라 생각하면 이해하기 쉽다. 그 이유는 개념적으로 비슷한 성격을 가지고 있기 때문입니다. CLR과 JVM은 특정 플랫폼에 종속적이지 않도록 하부 구조만을 제공한다는 점입니다. 물론 이 둘의 태생적 특성상 CLR은 Windows 계열에서, JVM은 Unix(Linux, Solaris) 계열에서 많이 사용됩니다. 하지만 플랫폼에 종속적이지 않기 때문에 이론적으로는 CLR이 Unix계열에서, JVM이 Windows계열에서 사용 할 수 있습니다. 실제로 Java는 Windows에서도 사용하고 있고, CLR의 일부 기능인 CLI 2는 ECMA 3에 제출되어 있습니다. 4
C# code를 Compile하면 MSIL라는 중간 언어로된 파일을 만들어 냅니다. 이는 Windows가 바로 읽어 낼 수 있는 Native code(또는 Machine code라 한다.)가 아닙니다. 이렇게 만들어진 MSIL 파일은 어플리케이션이 실행 될 때 CLR이 읽어 들여 OS가 이해할 수 있는 네이티브 코드로 컴파일 하여 실행 시킵니다. 이 방법이 JIT(Just-In-Time) Compiler를 통해 실행에 필요한 코드를 실시간으로 컴파일 해서 실행하는 방법 입니다. 5
그럼 왜 이렇게 번거롭게 MSIL코드를 만들어내 다시 컴파일 하는지에 대해서는 위에 설병한 바와 같습니다. 이를 통해 플랫폼에 비종속적이 될 수 있으며 .NET Platform에서 지원하는 언어가 C#만이 아닌 다른 언어로 확장 가능하기 때문입니다. 만약 위와 같이 두번의 컴파일을 하지 않고 한번에 컴파일로 네이티브 코드를 만들어 낸다면 컴파일에 부담을 줄어들지만 모든 플랫폼(Windows, UNIX 등)에서의 실행및 최적화된 성능을 보장하지 못하게 됩니다. 지금까지 설명한 내용을 그림으로 보면 다음과 같습니다.
[그림 1. C#에서 OS 및 각종 플랫폼 까지 / 출처 : 필자]
지금까지 장황하게 설명된 내용을 그리면 위와같은 그림이 됩니다. 여기서, 그림을 잘 보면 JIT Compiler가 CLR 내부 왼쪽에 위치해 있고 오른쪽은 비어 있습니다. 이는 CLR내부에는 JIT Compiler뿐만 아니라 다른 것들도 있다는 표시 입니다. 그리고 이중 대표적인 부분은 바로 Garbage Collector(Collection)입니다.
MSIL로 만들어진 파일이 CLR을 거쳐 실행하게 되면 메모리상에 존재하게 됩니다. 이는 CLR에서 실행에 필요한 부분은 그때그떄 사용하기 때문에 한번 실행한 영역은 메모리에 두어 다음 실행시 컴파일하지 않고 그대로 다시 사용해 컴파일 부담을 줄이기 위함입니다. 하지만 이런 식으로 계속 사용하게 되면 메모리에 끝없이 컴파일한 부분이 쌓이게 되고 그에 따른 문제가 발생하게 됩니다.때문에 CLR 내부에 존재하는 가비지 콜렉터가 사용자가 알 수 없는 시간단위로, 또는 행위 단위로 메모리를 체크하면서 메모리내에 존재하는 컴파일된 영역을 체크하게 됩니다. 그리고 해당 메모리 영역에 실행 여부를 판단하여 필요없다고 판단된 부분은 해당 메모리 영역을 반환하여 메모공간을 유지하게 됩니다.
이런 이유에서 .NET Framework를 사용하는 프로그램들은 첫 실행이 일반 Win32 프로그램보다 속도가 느리고, 이 후의 실행은 큰 차이가 없다는 것을 느끼는 것입니다.
.NET 플랫폼의 또 다른 구성 요소로 공용 형식 시스템(Common Type System, CTS)이 있다. CTS에는 모든 데이터 형식과 런타임에 지원되는 프로그래밍 구조가 완전하게 기술되어 있고, 이 항목들이 서로 어떻게 상호작용하고, .NET 메타 데이터 포맷에는 어떻게 나타나는지 정의되어 있다.
2.2 CTS : Common Type System
CLS를 포함한 .NET Framework의 중요 기반이며 .NET 언어들이 공통적으로 사용하는 타입체계를 정의하는 .NET Framework의 Type System 입니다. 이는 .NET 언어들이 사용하는 공동적인 타입에 대한 약속이며 MSIL에서 사용 가능한 타입에 집합입니다. 이를 통해 각기 다른 언어로 코딩된 소스들이 .NET Framework에서 호환성을 유지하며, 상호 운영성을 보장합니다.
'A' 라는 동작을 하는 기능 Class를 C#에서 작성하고, VB.NET에서 작성한다면 다른 언어로 작성 되었지만 CTS를 기반으로 작성되었기 때문에 .NET이 보는 관점에서는 동일한 기능을 수행하는 클래스로 보게 됩니다. CTS는 값 타입(Value Type)과 참조 타입(레퍼런스 타입, Reference Type)에 두가지로 나눌 수 있습니다.
Value Type : 의미 그대로 값(데이터)을 가지고 있는 타입을 말합니다.
Reference Type : 역시 의미 그대로 값(데이터)를 참조하고 있는 타입을 말합니다.
이 Value Type과 Reference Type은 추가로 올려질 '보충' 포스트에서 나름 상세하게 다루도록 하겠습니다.
2.3 CLS : Common Language Specification
.NET Framework를 사용하려 하는 모든 언어에서 동일한 방식으로 접근 가능한 코드를 생성하기 위해 .NET을 위한 컴파일러가 지원해야 하는 최소한의 표준 규약(기술한 지침서) 입니다. 이는 MSIL에 범위가 포괄적인대 있습니다.
역시 흔한 예제인 문자열 연결로 설명 하자면 C#에 경우 문자열과 문자열은 다음의 '+' 더하기 기호로 붙일 수 있습니다. 간단하게 표현해서
"C#" + "VB"
이렇게 말합니다. 하지만 Visual Basic에 경우 '&' 앰퍼샌드를 사용해서 더하게 됩니다.
"C#" & "VB"
이렇게 서로 다른 표현 방식을 사용하지만 문제없이 동작하는 것은, 컴파일시 동일한 MSIL을 만들어 내기 때문입니다.(언어간 문법 극복) 동일한 MSIL을 만들어내는 근거는 CLS를 기반으로 하고 있기 때문입니다. 또 다른 예를 들어보자면 C#에 경우 사용할 수 있는 Int가 4가지 있습니다. 'int, Int16, Int32, Int64' 보편적으로 'int'가 사용되며 'int'는 'Int32'와 동일합니다. 이를 포함해서 다시 말하면 Int의 종류는 3가지 입니다. 'Int16, int(Int32), Int64', 하지만 Visual Basic의 경우 Int32만 인식하고 이를 Integer라는 키워들 이용해 사용합니다. 하지만 프로그램은 문제없이 돌아갑니다. 이 역시 CLS를 따르기 때문입니다.
하지만 그렇다고해서 CLS가 만능은 아닙니다. 그 이유는 CLS에 경우 대소문자를 구분하지 않습니다. 하지만 C#은 대소문자를 구분합니다. 만약 C#에서 'Method, mEthod, meThod, metHhod ...' 이렇게 동일하지만 대소문자가 다른 메소드가 존재한다고 하면 문제가 발생되지 않으나 VB에서 가져다 쓸때는 문제가 발생하게 됩니다. VB는 대소문자를 구별하지 않기 때문입니다. 결국 C#에서 'Int16, int(Int32), Int64'를 사용하는건 CLS를 따르지만 모두 따르는것이 아니라 C# 내에서 유요한 CLS를 따른다 보시면 됩니다. VB는 VB에서 유요한 CLS를 따른다 보시면 됩니다. 그렇다면 C#에서 만들어낸 부분을 VB에서 사용 한다고 하면 'int(Int32)'로 정수를 표현하고, Method1, Method2, Method3 ... 이런식으로 사용하게되면 문제없이 CLS를 기반해 사용할 수 있게 됩니다.
위에서 말한 'Int16, int(Int32), Int64'는 CTS에서 정의하는 형식(Type)들 입니다. 그런데 CLS에서도 정의를 하고 있습니다. 이는 CLS가 CTS에 의해 정의된 하위 집합구성으로 볼 수 있기 때문입니다.
2.4 CLR, CTS, CLS
그럼 이 어려운 CLR, CTS, CLS를 그림으로 보자면??
[그림 2. CLR, CTS, CLS / 출처 : 필자]
CLR : .NET의 Engine
CTS : .NET의 Type 약속/정의/규약/규정 ...
CLS : .NET의 최소 약속/정의/규약/규정 ...
이를 묶어 놓은것이 바로 지금까지 말해온 .NET Framework 입니다.
3. .NET Framework
3.1 Version : 2.0 > 4.0, 그럼 3.0과 3.5는?
.NET Framework는 지금까지 1.0 > 1.1 > 2.0 > 3.0 > 3.5 > 4.0으로 발전해 왔습니다. 하지만 실질적으로 Engine에 버전은 2.0에서 머물러 잇다가 .NET Framework 4.0이 발표되면서 같이 4.0이 나오게 되었습니다. 그래서 Visual Studio 2008을 설치하거나 .NET Framework 3.5를 설치 하더라도 제어판 > 관리 도구 > 서비스에서 .NET Framework에 대한 부분을 확인해 보면 다음과 같은 부분을 발견할 수 있습니다.
(여기서 말하는 .NET Framework의 버전, .NET Framework Engine버전은 결국 CLR의 버전을 말합니다. 단지 명확한 표현으로 CLR 버전을 사용해야 하나 버전명으로 Microsoft에서 .NET Framework X.X로 사용하기 때문에 혼용해서 사용합니다.)
[그림 3. .NET Framework 2.0, 4.0 / 출처 : 필자]
이름은 다를 수 있지만 'Microsoft .NET Framework ~'이와같은 방식으로 쓰여 있으며 버전이 'v2.0.~'으로 되어 있을 것입니다. 필자는 .NET Framework 4.0이 설치되어 있기 때문에 2.0과 4.0이 모두 보이고 있으며 중간에 3.0이나 3.5는 보이지 않습니다. 이는 .NET Framework는 2.0까지 Bug fix와 .NET Framework에 자체적인 기능개선이 이루어 졌기 때문입니다.
'그렇다면 3.0, 3.5는 추가되지 않은 것이냐?'
그렇지 않습니다. 기능이 추가 되었습니다. 단지 2.0으로 가능한 기능들이라 보시면 됩니다.
'즉, 2.0에 Engine(CLR)을 수정하지 않아도 기능 구현이 가능했다.'
어떻게? Library 형태로 기능을 구현했기 때문입니다. 3.0에서는 WPF, WCF 6, WF 7, Windows CardSpace가 추가되었는대 이 기능모두 Library형태로 추가되었습니다. 그렇기 때문에 .NET Framework의 Engien버전을 올릴 필요가 없었습니다. 8
이로써 .NET의 철학 - Part .01을 마치도록 하겠습니다. 다음 Part .02에서는 기본 클래스 라이브러리(BCL : Base Class Library)를 다루겠습니다.
PS : 틈틈이 작성하기 때문에 작성에 오랜 시간이 소요 됩니다. 다음 포스팅은 언제가 될지 모르지만 어찌되었뜬 포스팅 됩니다.
오타, 맞춤법, 잘못된 내용은 고민마시고 과감하게 댓글달아 주세요!
감사합니다!
- .NET Framework기반으로 만들어진 모든 코드 C#, VB.NET 등 [본문으로]
- Virtual Machine의 준말이며 Java Virtual Machine을 줄여 JVM이라고 한다. 결국 같은말 입니다. [본문으로]
- Common Language Infrastructure : 공통 언어 구조, 공통 언어 하부구조, 공통 언어 인프라, 공통 언어 기반(http://ko.wikipedia.org/wiki/공통_언어_기반) [본문으로]
- European Computer Manufacturers Association : 유럽 전자계산기 제조공업회, 유럽 컴퓨터 메이커협회이며 1994년 ECMA에서 Ecma International이라는 이름을 바꾸었 습니다.(http://ko.wikipedia.org/wiki/Ecma) [본문으로]
- Microsoft Intermediate Language, 줄여서 IL로 표현 하기도 하며 다른 이름으로 Assembly라고 하기도 합니다. [본문으로]
- Windows Presentation Foundation [본문으로]
- Windows Communication Foundation [본문으로]
- Windows WorkFlow Foundation [본문으로]