C# 기초 - .NET 깊이 보기 : Intermediate Language(IL)
Programming/C# / 2010. 5. 26. 20:44
오늘은 .NET의 핵심 요소중 한 가지인 Intermediate Language(IL 혹은 MSIL 그리고 어색하지만 우리말로하면 중간언어)에 대해서 이야기 해보고자 한다.
Java는 알려진 바와 같이 Byte code로 컴파일 되어 실행 시 자바 가상머신을 통해 인터프리트 된다. .NET의 IL(Intermediate Language)은 Java의 Byte code와 비슷한 개념으로 생각하면 될 것이다.
그것이 전부냐고 묻는다면, 당연히 아니다.
.NET에서 프로그래머가 코드를 작성하고 컴파일하면, 그 결과로 IL 코드가 생성된다. IL코드는 JIT(Just-In-Time)컴파일러에 의해 Native 코드로 컴파일된다. (인터프리트 되는 것이 아니다.)
Java의 경우 Byte code를 인터프리트 하는 과정에서 발생하는 프로그램의 Performance Loss는 상당하다. 하지만, (MS측의 말에 따르면) .NET에서는 JIT컴파일러를 이용하여 컴파일하므로 Performance Loss의 상당부분을 축소시킬 수 있다고 한다.
IL사용의 또 다른 이점은 바로 객체지향 환경에서 언어 상호운용(Language Interoperability)을 가능하게 한다는 것이다. 즉 한 언어로 작성된 코드를 다른 언어에서도 이용할 수 있다는 것이다. (단, 이를 위해서는 몇 가지 방법론상의 제한적 요소가 필요하다.) 또한 IL을 통해 Platform의 독립성이 보장된다.
그럼 IL의 특징에 대해 좀 더 살펴보자.
객체지향적 프로그래밍
.NET에서는 20여년 가까이 사용되어온 객체지향적 프로그래밍을 효과적으로 사용하고 있다. 그 결과로 우리는 코드의 재사용, 다형성, 캡슐화등의 객체지향의 장점을 최대한 활용할 수 있다.
IL에서는 상속과 인터페이스를 지원한다.(모든 객체는 object 객체를 상속받는다.) .NET의 인터페이스는 기존의 COM 인터페이스와 유사한 개념으로 생각하면 될 것 이다. 그러나 더 이상 IUnknown와 GUID로 인해 골치를 썩힐 필요는 없다.(이 문제는 Assembly가 대신 해결해준다. 후에 자세히 설명하겠다.)
IL은 특히 “단일구현상속”과, “다중인터페이스상속”을 지원한다. (말이 좀 혼란스러울까?) 좀더 자세히 설명하자면, “단일구현상속”은 객체의 구현을 오직 한 객체에서만 상속 받을 수 있다는 것이다. 그리고 “다중인터페이스상속”이란 객체의 전체 구현이 아닌 인터페이스는 여러 개를 상속 받을 수 있음을 의미한다. (단지 글로써 이해 하는 것은 힘들겠지만, 이 연재를 통해 깊이 소개 될 것이므로 일단 개념으로 접어두기 바란다.)
Value 타입과 Reference 타입
IL에서 지원하는 데이터 타입은 크게 두 가지로 나눌 수 있다. 그것이 바로 Value 타입과 Reference타입이다.
각각의 특징을 간단히 요약하자면 다음과 같다.
Value 타입은 변수에 데이터가 직접적으로 저장되는 타입을 말하며, 일반적으로 스택에 저장된다. 데이터를 직접 액세스하므로 Reference 타입보다 속도가 빠르다.
Reference 타입은 C/C++의 포인터를 와 유사한 개념으로 이해하면 될 것이다.(물론 차이점은 있다.) Reference 타입은 주소를 저장하며, 일반적으로 Reference의 인스턴스는 힙에 저장된다.
강력한 타입 시스템의 지원
기존의 C/C++에서의 타입 캐스팅(Type Casting)은 편리하면서도 상당한 위험부담을 필요로 했다. 예를 들자면 상당한 Performance의 부담을 요구했으며 데이터 타입의 안정성을 깰수도 있었다.
하지만, .NET의 Managed Code는 이런 문제를 해결해 준다. CLR에 의해서 모든 형의 안정성이 보장된다. 물론 이것으로 인해 약간의 Performance를 손해 보는 것도 사실일지 모르나, 그 만큼 얻는 이득도 있다.
마치면서
특별한 구현없이 연속되는 개념설명에 혹시 지쳤을지 모르겠다. 지금 이해가 되지 않는다면 일단은 지나쳐 버리는 것도 괜찮을 것 같다. 그냥 편안하게 읽어주길 바란다. 그리고 후에 C#에 대한 연재가 이어지고 그 때 다시 이 글을 보게 된다면 한층 도움이 될 것이다. 언제든지 질문이 있으면 이곳 의견게시에 올려주길 바라며 다음 시간에는 “언어 상호운용(Language Interoperability)”에 대해 이야기 해보도록 하겠다
Java는 알려진 바와 같이 Byte code로 컴파일 되어 실행 시 자바 가상머신을 통해 인터프리트 된다. .NET의 IL(Intermediate Language)은 Java의 Byte code와 비슷한 개념으로 생각하면 될 것이다.
그것이 전부냐고 묻는다면, 당연히 아니다.
.NET에서 프로그래머가 코드를 작성하고 컴파일하면, 그 결과로 IL 코드가 생성된다. IL코드는 JIT(Just-In-Time)컴파일러에 의해 Native 코드로 컴파일된다. (인터프리트 되는 것이 아니다.)
Java의 경우 Byte code를 인터프리트 하는 과정에서 발생하는 프로그램의 Performance Loss는 상당하다. 하지만, (MS측의 말에 따르면) .NET에서는 JIT컴파일러를 이용하여 컴파일하므로 Performance Loss의 상당부분을 축소시킬 수 있다고 한다.
IL사용의 또 다른 이점은 바로 객체지향 환경에서 언어 상호운용(Language Interoperability)을 가능하게 한다는 것이다. 즉 한 언어로 작성된 코드를 다른 언어에서도 이용할 수 있다는 것이다. (단, 이를 위해서는 몇 가지 방법론상의 제한적 요소가 필요하다.) 또한 IL을 통해 Platform의 독립성이 보장된다.
그럼 IL의 특징에 대해 좀 더 살펴보자.
객체지향적 프로그래밍
.NET에서는 20여년 가까이 사용되어온 객체지향적 프로그래밍을 효과적으로 사용하고 있다. 그 결과로 우리는 코드의 재사용, 다형성, 캡슐화등의 객체지향의 장점을 최대한 활용할 수 있다.
IL에서는 상속과 인터페이스를 지원한다.(모든 객체는 object 객체를 상속받는다.) .NET의 인터페이스는 기존의 COM 인터페이스와 유사한 개념으로 생각하면 될 것 이다. 그러나 더 이상 IUnknown와 GUID로 인해 골치를 썩힐 필요는 없다.(이 문제는 Assembly가 대신 해결해준다. 후에 자세히 설명하겠다.)
IL은 특히 “단일구현상속”과, “다중인터페이스상속”을 지원한다. (말이 좀 혼란스러울까?) 좀더 자세히 설명하자면, “단일구현상속”은 객체의 구현을 오직 한 객체에서만 상속 받을 수 있다는 것이다. 그리고 “다중인터페이스상속”이란 객체의 전체 구현이 아닌 인터페이스는 여러 개를 상속 받을 수 있음을 의미한다. (단지 글로써 이해 하는 것은 힘들겠지만, 이 연재를 통해 깊이 소개 될 것이므로 일단 개념으로 접어두기 바란다.)
Value 타입과 Reference 타입
IL에서 지원하는 데이터 타입은 크게 두 가지로 나눌 수 있다. 그것이 바로 Value 타입과 Reference타입이다.
각각의 특징을 간단히 요약하자면 다음과 같다.
|
Value 타입 | Reference 타입 |
무엇이 저장되는가? | 데이터 | 데이터가 위치하는 주소 |
메모리의 어느부분을 이용하는가? | 일반적으로 스택(Stack) | 일반적으로 힙(Heap) |
Value 타입은 변수에 데이터가 직접적으로 저장되는 타입을 말하며, 일반적으로 스택에 저장된다. 데이터를 직접 액세스하므로 Reference 타입보다 속도가 빠르다.
Reference 타입은 C/C++의 포인터를 와 유사한 개념으로 이해하면 될 것이다.(물론 차이점은 있다.) Reference 타입은 주소를 저장하며, 일반적으로 Reference의 인스턴스는 힙에 저장된다.
강력한 타입 시스템의 지원
기존의 C/C++에서의 타입 캐스팅(Type Casting)은 편리하면서도 상당한 위험부담을 필요로 했다. 예를 들자면 상당한 Performance의 부담을 요구했으며 데이터 타입의 안정성을 깰수도 있었다.
하지만, .NET의 Managed Code는 이런 문제를 해결해 준다. CLR에 의해서 모든 형의 안정성이 보장된다. 물론 이것으로 인해 약간의 Performance를 손해 보는 것도 사실일지 모르나, 그 만큼 얻는 이득도 있다.
- CLR은 프로그램을 실행하기전에 실행 권한이라던가, 해당 코드가 실행중인 다른 프로그램에 피해를 주지 않는지 검사한다. 이것을 통해서 데이터 타입과 관련된 잘못된 코드는 실행할 수 없게 한다.
- 가비지 컬렉터를 이용함으로써 자동적인 메모리 자원관리를 지원한다. 즉 더 이상 사용되지 않는 데이터가 차지하고 있는 메모리 자원을 자동적으로 회수한다.
- 강력한 데이터 타입의 지원을 통하여 언어 상호운용(Language Interoperability)을 가능하게 한다.
마치면서
특별한 구현없이 연속되는 개념설명에 혹시 지쳤을지 모르겠다. 지금 이해가 되지 않는다면 일단은 지나쳐 버리는 것도 괜찮을 것 같다. 그냥 편안하게 읽어주길 바란다. 그리고 후에 C#에 대한 연재가 이어지고 그 때 다시 이 글을 보게 된다면 한층 도움이 될 것이다. 언제든지 질문이 있으면 이곳 의견게시에 올려주길 바라며 다음 시간에는 “언어 상호운용(Language Interoperability)”에 대해 이야기 해보도록 하겠다
반응형
'Programming > C#' 카테고리의 다른 글
Windows Forms 컨트롤 사용 방법 시리즈 – Visual C# (0) | 2010.05.27 |
---|---|
JIT (0) | 2010.05.26 |
C# 에서 windows API 쓸수 있는 방법 도와 주는 사이트 (0) | 2010.05.25 |
[펌] String Formatting in C# (0) | 2010.05.25 |
C# 관련 사이트 (0) | 2010.05.20 |