.NET 플랫폼과 CLR
목차
본격적으로 C#을 학습하기에 앞서 마이크로 소프트의 .NET 의 역사와 구조에 대하여 대략적으로 알아보는 것도 나쁘지 않을 듯 합니다. 소프트웨어 업계의 개발 환경은 다른 분야에 비해 너무 빨리 변해서 현재 시점에서 보면 도대체 왜 이런 기술이 나와있을까 싶은 것도 그 시대의 입장에서 바라보면 쉽게 이해가 될 때가 있습니다.
.NET은 지금은 데스크탑 응용프로그램 부터 웹서버, 모바일 등을 아우르는 거대한 크로스 플랫폼 생태계로 확장하고 있는데 2002년 마이크로 소프트 사가 .NET 프레임워크의 첫번째 버전을 출시했을 때는 기존 윈도우 시스템에서 발생하는 개발환경의 문제들을 해결하기 위한 방법이었습니다. 90년대에 윈도우에서는 마이크로 소프트가 개발한 WIN32 API, MFC, COM 기술들이 각각 자신들의 문제를 가진 상태로 따로 관리되고 있었습니다. 이 때 이미 자바는 write once run anywhere(한번 작성하면 어디서든 작동한다)는 크로스 플랫폼 개념을 도입하고 완전한 객체지향, 오픈소스 커뮤니티로 진보하고 있었는데 마이크로 소프트의 제품군들은 통합이 안되고 서로 충돌하고 있었습니다.
이런 문제들을 해결한 차기 윈도우 개발 시스템을 목표를 출시한 것이 .NET Framework 입니다. 물론 이 단계에서는 아직 완전한 크로스 플랫폼 개념은 없었습니다. PC뿐 아니라 PDA, 스마트폰, 서버에 구현하려는 목적은 있었으나 자바 처럼 처음부터 운영체제를 넘나드려는 목적은 없었습니다. .NET Framework 는 윈도우 계열 운영체제 안에서 다양한 장치에 적용되기 위해 개발되었습니다. 2021년인 지금은 MS도 많이 바뀌었고 많은 부분에서 오픈소스 정책으로 방향 전환을 했지만 .NET이 처음 나온 2002년도는 지금과 많이 달랐습니다.
MS가 상당 기간 소프트웨어 산업에서 독점을 한 기간과 맞물려서 현재까지도 오픈소스 커뮤니티에서 많은 비판을 받고 있습니다. 서양권에서 빌게이츠에 대한 대중의 평가가 좋지 않은 것과 전혀 무관하다고 할 수는 없을 것 입니다. 뭐 특정 회사를 비판하려는 내용은 아니지만 어쨋든 오픈소스 지지자들의 관점에서 특정 개발 플랫폼을 하나의 회사가 판매하는 운영체제 안에서만 돌아가게 한다는 것은 좋게 보이지 않습니다. 어쨋든 MS는 .NET Core을 오픈소스로 리눅스와 Mac OS까지 확장했습니다. 다소 민감한 주제라서 더는 언급하지 않겠습니다만, 유닉스 계열(리눅스, Mac OS) 개발 환경에서는 명확해 보이는 구조도 윈도우의 .NET에서는 뭔가 복잡하고 답답한게 좀 있습니다. 어떻게 보면 MS의 문제라고 볼 수도 있고, 관점을 바꿔서 GNU 리눅스와 자바가 시대를 훨씬 앞서갔다고 볼 수도 있습니다.
컴퓨터 언어는 필요에 의해서 발달합니다. 컴퓨터가 세상에 나온 이후 프레임워크의 중요한 방향성이 있는데 그것은 하나의 코드를 모든 시스템에 적용하는 것 입니다. 자바의 슬로건이었던 write once run anywhere 입니다. 이것은 멋있는 말이지만 기존의 구조를 완전히 바꿔야만 가능합니다. 한번 작성해서 모든 시스템에서 동작하는 코드는 응용 프로그래머 레벨이고 그 코드가 여러 운영체제와 CPU에서 제대로 작동하도록 누군가 환경을 만들어 놔야 합니다. .NET 플랫폼에서 그 환경은 CLR (Common Language Runtime – 공통 언어 실행환경) 입니다.
CLR
Common Language Runtime – 공통 언어 런타임은 .NET 을 구성하는 핵심 요소입니다. 기존의 네이티브 프로그래밍과 비교해 보면 C언어는 소스 코드를 시스템에 맞춰서 오브젝트 코드로 컴파일 후 링커로 그 시스템에서만 작동하는 실행파일을 만듭니다. 처음 컴파일 할 때 소스 코드를 비롯한 모든 라이브러리를 네이티브 코드로 변환합니다. 메모리 관리는 직접해야 하고 일단 실행이 되면 CLR 처럼 중간의 개입이 없습니다.
반면 .NET 에서는 우선 C# 소스 코드를 컴파일하여 어셈블리를 만듭니다. 어셈블리는 소스코드와 네이티브 기계어의 중간적인 코드로써 CIL (Common Intermediate Language – 공통 중간 언어)와 타입 메타데이타, 보안 정보가 들어있습니다. 이것은 실행시간에 JIT 컴파일러에 의해서 운영체제와 하드웨어에 맞는 네이티브 코드로 변환되서 실행됩니다. 이 네이티브 코드를 런타임에서 책임지고 실행시키는 것이 CLR 입니다. CLR은 메모리 관리와 GC(가비지 콜렉션), 코드 검증, 예외 처리 등을 하며 C# 프로그램이 시작하고 끝날 때 까지 관리합니다. 한번 실행된 코드는 캐시되기 때문에 반복실행 시 속도가 빨라집니다.
중간 코드인 CIL 로 변환하는 것은 자바 언어의 JVM의 바이트코드와 닮았습니다만 .NET은 C#을 비롯하여 VB .NET, C++ 등 약 30개의 CLI (Common Language Infrastructure) 언어가 하나의 CLR에서 함께 작동이 가능합니다. 이는 .NET의 넓은 통합과 확장성을 의미합니다. 다른 언어로 CLR에서 같은 BCL(Base Class Library)를 사용할 수 있습니다.
요약
.NET 플랫폼과 CLR 을 설명하기엔 너무 빈약한 내용이지만 C#을 시작하는데 있어서 약간의 아이디어는 필요하기 때문에 작성해봤습니다. 또 코딩도 시작하기 전에 아키텍처에 대한 내용에 시간을 너무 많이 투자하는 것도 좀 속도가 나지 않겠지요. 사실 잘 몰라도 코딩하는데는 지장이 없는 내용들일지도 모릅니다. 자세한 내용이 궁굼할 때는 마이크로 소프트의 문서를 읽어보고 구글 검색으로 .NET에 관한 칼럼을 읽어 보는 것을 추천합니다.
Microsoft 의 공식 .NET 튜토리얼을 진행하는 Scott Hanselman의 아래 유튜브 영상은 현재의 닷넷 생태계를 잘 설명하고 있습니다.
마이크로 소프트는 다소 모호한 마케팅 용어처럼 들리는데 Scott 이 정의하는 .NET 은 생태계이며 언어, 런타임, 라이브러리라고 합니다.
참고문서
https://docs.microsoft.com/ko-kr/dotnet/