Информация о полезной статье
.NET: Компоненты и процесс компиляции
Оглавление
- Полная схема процесса
- Этапы процесса компиляции и исполнения
- .NET Platform
- Компоненты .NET Runtime
- Код
- Компиляция и запуск
- Сборка (Assembly)
- CLI [Common Language Infrastructure]
Полная схема процесса
┌─────────────────────────────────────────────────────────────────┐
│ ЭТАП 0: НАПИСАНИЕ КОДА (Development) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Development │
│ │ │
│ ├─[BCL]─────────> Использует библиотеки классов │
│ │ │
│ └─[DLR]─────────> Обрабатывает dynamic типы (если есть) │
│ │
│ Результат: Source Code (.cs/.vb файлы) │
│ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ ЭТАП 1: COMPILE TIME (Сборка) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Source Code │
│ │ │
│ ├─[C# Compiler]─> Byte Code (CIL) │
│ │ │
│ ├─[CTS]─────────> Проверка типов │
│ │ │
│ └─[Metadata]─────> Сбор метаданных │
│ │
│ Результат: Assembly (.exe/.dll) │
│ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ ЭТАП 2: RUNTIME (Исполнение) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Assembly │
│ │ │
│ ├─[CLR]─────────> Загружает и управляет выполнением │
│ │ │
│ ├─[VES]─────────> Загрузка сборки │
│ │ │
│ ├─[JIT]──────────> Byte Code → Native Code │
│ │ │
│ ├─[Metadata]─────> Управление исполнением │
│ │ │
│ └─[CLS]──────────> Гарантия совместимости языков │
│ │
│ Результат: Выполнение программы (Process) │
│ │
└─────────────────────────────────────────────────────────────────┘
Этапы процесса компиляции и исполнения
0) Написание кода (Development)
- BCL / .NET Libraries: Предоставляет библиотеки классов для разработки
- DLR: Обрабатывает динамические типы (
dynamic), если они используются- Результат: Source Code (.cs/.vb файлы)
1) Во время сборки (COMPILE TIME)
- C# Compiler / VB.Net Compiler: Преобразует Source code в Byte code (CIL)
- CTS: Обеспечивает согласованность типов данных в Byte code
- Metadata: Собираются и включаются в сборку, содержащую информацию о структуре кода и типах
- Результат: Assembly (.exe/.dll)
2) Во время исполнения (RUNTIME)
- CLR: Загружает и управляет выполнением Assembly
- VES: Загружает сборку в память
- JIT: Компилирует Byte code в Native code, оптимизированный под конкретную платформу
- Metadata: Используются для управления исполнением кода
- CLS: Гарантирует, что код, написанный на разных языках, может взаимодействовать в рамках .NET
- Результат: Выполнение программы (Process)
Примечание: FCL используется в .NET Framework вместо BCL
.NET Platform
.NET Platform состоит из большего числа компонентов, на данном этапе было важно только .NET Runtime
┌──────────────────────────────────────┐
│ .NET Platform │
├──────────────────────────────────────┤
│ ┌────────────┐ ┌──────────────┐ │
│ │ .NET SDK │ │ .NET Runtime │ │
│ └────────────┘ └──────────────┘ │
└──────────────────────────────────────┘
.NET SDK [Software Development Kit]
Набор инструментов для разработки, компиляции и сборки .NET приложений.
- Включает компиляторы (Roslyn), инструменты сборки (MSBuild)
- Предоставляет CLI инструменты (
dotnetкоманды)- Содержит библиотеки и шаблоны проектов
- Используется на этапе разработки и компиляции
.NET Runtime
Среда выполнения для .NET приложений, обеспечивает выполнение скомпилированного кода.
- Загружает и выполняет .NET приложения
- Управляет памятью, безопасностью, типами
- Предоставляет различные реализации выполнения
Компоненты .NET Runtime:
- CoreCLR [Core Common Language Runtime]
- BCL [Base Class Library]
- DLR [Dynamic Language Runtime]
- Native AOT [Ahead-of-Time Compilation]
Компоненты .NET
.NET Runtime состоит из 3 основных компонентов:
┌─────────────────────────────────────────────────┐
│ NET Runtime Components │
├─────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌──────┐ ┌──────┐ │
│ │ CoreCLR │ │ BCL │ │ DLR │ │
│ └─────────┘ └──────┘ └──────┘ │
│ │
└─────────────────────────────────────────────────┘
CoreCLR [Core Common Language Runtime]
Общеязыковая исполняющая среда, управляет выполнением .NET приложений.
- Работает с Byte code и Native code
- Принимает Byte code (IL) из Assembly
- Компилирует его в Native code через JIT компилятор
- Управляет выполнением Native code на протяжении всего жизненного цикла программы
Примечание: CLR — термин для .NET Framework.
BCL [Base Class Library]
Библиотеки классов, предоставляющие готовые API для разработки.
- Используется при написании Source code
- Предоставляет классы и API для разработки (коллекции, работа с файлами, сеть и т.д.)
- Используется в Source code на C# или VB.Net через директивы
usingПримечание: FCL — термин для .NET Framework. CoreFX для Core.
DLR [Dynamic Language Runtime]
Среда, поддерживающая работу с динамическими типами (
dynamic).
- Работает с Source code, использующим
dynamicтипы- Обрабатывает динамические типы во время выполнения
- Обеспечивает позднее связывание (late binding) для динамических операций
Native AOT [Ahead-of-Time Compilation]
Ниже, в разделе компиляции.
Код
Код проходит через 3 состояния:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Source code │ --> │ Byte code │ --> │ Native code │
│ (C#/VB) │ │ (IL) │ │ (Machine) │
└─────────────┘ └─────────────┘ └─────────────┘
[Source code]
Код написанный разработчиком на одном из поддерживаемых языков (C# или VB.Net), код высокого уровня.
- Хранится в файлах с расширениями
.cs(C#) или.vb(VB.Net)- Содержит логику приложения, классы, методы, переменные
- Использует FCL (Framework Class Library) в .NET Framework или BCL / .NET Libraries (ранее CoreFX) в современном .NET - библиотеки классов для разработки
- При использовании
dynamicтипов задействуется DLR (Dynamic Language Runtime)- Компилируется компилятором языка (C# Compiler или VB.Net Compiler) в Byte code
[Byte code]
Промежуточный код (IL), скомпилированный из Source code, платформо-независимый формат.
- Создается с помощью C# Compiler или VB.Net Compiler из Source code
- Хранится в сборках (Assembly) - файлах
.exeили.dll- По синтаксису напоминает ассемблер, но не является машинным кодом
- Содержит метаданные о типах, методах и структуре программы
- Не может выполняться напрямую процессором, требует компиляции в Native code
- Обрабатывается CLR / CoreCLR во время выполнения
- Один и тот же Byte code может выполняться на разных платформах благодаря кроссплатформенной среде выполнения
[Native code]
Машинный код конкретного процессора, который выполняется непосредственно процессором.
- Генерируется CoreCLR во время выполнения (runtime) из Byte code через JIT компилятор
- Платформо-зависимый код конкретного процессора (x86, x64, ARM и т.д.)
- Оптимизирован под конкретную платформу и архитектуру процессора (Windows, Linux, macOS)
- Выполняется напрямую процессором без дополнительной интерпретации
- Кэшируется в памяти для повторного использования
- Управляется CoreCLR на протяжении всего жизненного цикла выполнения
Виды Source code:
- Managed code — Созданный на базе .NET, под прямым контролем CLR
- Unmanaged code — Созданный вне .NET, требует явного освобождения памяти
Важно: Unmanaged code требует явного управления ресурсами для избегания утечек памяти.
Эволюция Byte code (IL):
CIL [Common Intermediate Language]
Низкоуровневый / промежуточный язык, по синтаксису напоминает ассемблер.
- Современное название промежуточного языка (IL)
- Используется для создания стандарта ECMA-335
- Является платформо-независимым форматом Byte code
MS IL [Microsoft Intermediate Language]
Старое название языка CIL, использовалось до стандартизации.
- Историческое название промежуточного языка
- Переименован в CIL для создания стандарта ECMA-335
- В настоящее время используется термин CIL
Компиляция и запуск
Процесс компиляции состоит из 2 этапов:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ COMPILE TIME │ --> │ RUNTIME │ --> │ EXECUTION │
│ │ │ │ │ │
│ Source Code │ │ Assembly │ │ Process │
└──────────────┘ └──────────────┘ └──────────────┘
COMPILE TIME (Этап компиляции)
Этап сборки, во время которого Source code преобразуется в Byte code и создается Assembly.
- C# Compiler или VB.Net Compiler компилирует Source code в Byte code (IL)
- CTS проверяет согласованность типов данных
- Metadata собираются и включаются в сборку
- Результат: Assembly (.exe/.dll) с Byte code, метаданными и манифестом
Команды для компиляции:
dotnet build- компилирует Source code в Byte code (IL), создает сборки (.dll/.exe)dotnet publish- компилирует и подготавливает приложение для развертыванияcsc.exe Program.cs- прямая компиляция C# через компилятор (C# Compiler)
RUNTIME (Этап выполнения)
Этап исполнения, во время которого Assembly загружается, Byte code компилируется в Native code и программа выполняется.
- CLR загружает и управляет выполнением Assembly
- VES загружает сборку в память
- JIT [Just-In-Time Compiler] компилирует Byte code в Native code (см. ниже)
- Metadata используются для управления исполнением
- CLS гарантирует совместимость языков
- Результат: Выполнение программы (Process), Native code выполняется процессором
Компилятор, который преобразует Byte code в Native code во время выполнения программы.
- Работает внутри CLR / CoreCLR во время выполнения (runtime)
- Компилирует Byte code в Native code "на лету" (just-in-time) по мере необходимости
- Оптимизирует код под конкретную платформу и архитектуру процессора
- Кэширует скомпилированный Native code в памяти для повторного использования
Команды для запуска:
dotnet run- компилирует (если нужно) и запускает приложениеdotnet MyApp.dll- запускает скомпилированную сборкуMyApp.exe- прямой запуск исполняемого файла (Windows)mono MyApp.exe- запуск через Mono runtime (кроссплатформенно)
Компиляция в 1 этап: Native AOT [Ahead-of-Time Compilation]
Метод компиляции Source code → Native code заранее, до выполнения программы без промежуточного Byte code.
- Компилирует Source code напрямую в Native code, минуя этап Byte code
- Выполняется во время сборки приложения (compile time)
- Результат: готовый к выполнению Native code без необходимости JIT компиляции
Преимущества:
- Уменьшает время на старте
- Увеличивает общую скорость выполнения
- Меньший размер приложения
Сборка (Assembly)
┌─────────────────────────────────────────────────┐
│ Assembly Components │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Manifest │ │ Metadata │ │ Byte code(IL)│ │
│ └──────────┘ └──────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────┘
Assembly (Сборка)
Результат процесса компиляции, единица развертывания и версионирования в .NET. Сборка содержит Byte code (IL), метаданные и манифест.
- Создается в результате компиляции: Source code → [Компилятор] → Byte code → упаковывается в Assembly
- Сборка может быть исполняемой (
.exe) или библиотекой (.dll)- Assembly загружается CLR/CoreCLR во время выполнения
- JIT компилятор преобразует Byte code из Assembly в Native code
Компоненты сборки:
Manifest (Манифест)
Часть сборки, описывает содержание сборки, версию, зависимости и метаданные.
- Содержит информацию о самой сборке (имя, версия, зависимости)
- Описывает, какие файлы и ресурсы входят в сборку
- Используется CLR для разрешения зависимостей и загрузки сборок
Metadata (Метаданные)
Информация о типах, методах, свойствах и структуре программы, хранящаяся в сборке.
- Описывают все типы и члены, определенные в сборке
- Собираются во время компиляции и включаются в Assembly
- Используются во время выполнения для управления исполнением кода
- Позволяют CLR работать с типами и методами без исходного кода
Byte code (IL) в сборке
См. выше раздел Код → [Byte code]
CLI [Common Language Infrastructure]
CLI состоит из 4 компонентов:
┌─────────────────────────────────────────────────┐
│ CLI Components │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────┐ │
│ │ CTS │ │ CLS │ │ VES │ │ Metadata │ │
│ └──────┘ └──────┘ └──────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────┘
CLI [Common Language Infrastructure]
Стандарт (ECMA-335), который определяет структуру сборок (Assembly), формат метаданных и процесс их выполнения. Обеспечивает единообразие для всех языков .NET.
- Определяет структуру сборок (Assembly) и формат метаданных
- Позволяет коду на разных языках взаимодействовать друг с другом
- Обеспечивает единую инфраструктуру для компиляции и выполнения .NET приложений
- Реализуется через компоненты: CTS, CLS, VES и Metadata
CTS [Common Type System]
Общая система типов в CLR, обеспечивает совместимость типов.
- Обеспечивает согласованность типов данных в Byte code во время компиляции
- Определяет правила для типов, которые должны поддерживать все языки .NET
- Гарантирует, что типы из разных языков могут взаимодействовать друг с другом
CLS [Common Language Specification]
Минимальный набор правил для всех языков .NET, определяющий совместимость между языками.
- Гарантирует, что код, написанный на разных языках, может взаимодействовать в рамках .NET
- Определяет подмножество CTS, которое должны поддерживать все языки .NET
- Обеспечивает межъязыковую совместимость на уровне компиляции и выполнения
VES [Virtual Execution System]
Загрузка и выполнение программ в среде CLI.
- Загружает сборку (Assembly) во время выполнения
- Использует метаданные для управления исполнением кода
- Обеспечивает виртуальную среду выполнения для .NET приложений
- Управляет жизненным циклом выполнения программы
Metadata [Метаданные]
Стандарт формата метаданных, определенный в CLI (ECMA-335), который описывает структуру информации о типах, методах и свойствах.
- Определяет формат хранения метаданных в Assembly (см. раздел Сборка (Assembly))
- Обеспечивает единообразие метаданных для всех языков .NET
- Позволяет VES и CLR работать с типами и методами без исходного кода
- Используется для межъязыкового взаимодействия через CTS и CLS