CLR

Common Language Runtime (сокр. CLR) — исполняющая среда для управляемого кода, разработанная корпорацией Microsoft и являющаяся ключевым компонентом платформы .NET[3]. CLR представляет собой реализацию спецификации Common Language Infrastructure (CLI). Среда управляет запуском, безопасностью и жизненным циклом приложений, написанных на любых CLR-совместимых языках, таких как C#, Visual Basic .NET и F#[4][5].

Общие сведения
Common Language Runtime
англ. Common Language Runtime
Область использования Разработка программного обеспечения, Платформа .NET
Дата появления 13 февраля 2002
Место появления Редмонд, Вашингтон, США[1]
Автор понятия Microsoft[2]

Определение

Common Language Runtime реализует спецификацию Common Language Infrastructure (CLI) и функционирует как виртуальная машина, которая:

  • переводит промежуточный код (CIL/MSIL) в машинные инструкции с помощью JIT-компиляции;
  • управляет памятью и сборкой мусора;
  • обеспечивает обработку исключений и безопасность типов;
  • предоставляет единый доступ к библиотеке классов .NET (FCL/BCL);
  • поддерживает межъязыковую совместимость за счёт Common Type System и Common Language Specification[6].[7]

Основные функции CLR:

  1. автоматическое управление памятью (Garbage Collector);
  2. JIT-компиляция CIL-кода;
  3. централизованная обработка исключений;
  4. модель безопасности и верификация кода;
  5. типобезопасность;
  6. управление потоками исполнения;
  7. работа с метаданными и рефлексия.

История

Разработка CLR началась в корпорации Microsoft 13 июня 1998 года[8] в штаб-квартире компании в Редмонде, штат Вашингтон.

Версии для .NET Framework:

  • CLR 1.0 — выпущена вместе с .NET Framework 1.0 13 февраля 2002 года[9].
  • CLR 1.1 — выпущена 3 апреля 2003 года, позже интегрирована в Windows Server 2003[10].
  • CLR 2.0 — вышла 27 октября 2005 года и использовалась в .NET Framework версий 2.0, 3.0 и 3.5. Ключевые нововведения: обобщения (generics), полноценная поддержка 64-битных систем и значительные улучшения в работе сборщика мусора (GC)[11].
  • CLR 4.0 — появилась 12 апреля 2010 года и стала основой для всех версий .NET Framework 4.x. В этой версии были внедрены поддержка асинхронного программирования (async/await), новый JIT-компилятор RyuJIT, поддержка инструкций SIMD и обновлённые механизмы безопасности[12].

Версии для .NET Core и .NET (CoreCLR): Начиная с 2016 года, вместе с выпуском .NET Core, была представлена CoreCLR — открытая, кроссплатформенная реализация CLR. С выходом .NET 5 в 2020 году CoreCLR стала единой средой выполнения для всей платформы .NET, ориентированной на высокую производительность, облачные и микросервисные сценарии[13].

  • CLR в .NET 6 (ноябрь 2021) — получила значительные улучшения производительности за счёт динамической профильной оптимизации (Dynamic PGO), нового AOT-компилятора Crossgen2 и полноценной поддержки архитектуры ARM64 (включая Apple silicon)[14][15].
  • CLR в .NET 7 (ноябрь 2022) — ключевым нововведением стала технология On-Stack Replacement (OSR), позволяющая «на лету» заменять код долго выполняющихся методов на более оптимизированный. Также была представлена компиляция в нативный код (Native AOT) для консольных приложений и осуществлён переход сборщика мусора на использование регионов памяти вместо сегментов[16][17].
  • CLR в .NET 8 (ноябрь 2023, LTS) — динамическая PGO была включена по умолчанию, что обеспечило прирост производительности до 15 %. Добавлена поддержка векторных инструкций AVX-512, а Native AOT стал доступен для ASP.NET Core. Сборщик мусора получил функцию DATAS для динамической адаптации к нагрузке[18][19].
  • CLR в .NET 9 (ноябрь 2024) — продолжены улучшения PGO, ускорена обработка исключений, а функция DATAS в GC включена по умолчанию. JIT-компилятор научился размещать на стеке «упакованные» объекты (boxed objects), снижая нагрузку на GC. Появились переключатели функций (Feature Switches) для уменьшения размера приложений при AOT-компиляции[20][21].
  • CLR в .NET 10 (план: ноябрь 2025, LTS) — основной фокус сделан на снижении «цены абстракций» (Deabstraction) за счёт расширенного анализа выхода (Escape Analysis), который позволяет размещать на стеке массивы и делегаты. JIT-компилятор получил возможность размещать поля структур в регистрах процессора и девиртуализировать вызовы интерфейсов для массивов. Добавлена поддержка инструкций AVX10.2[22][23][24].

JIT-компилятор

JIT-компилятор (англ. Just-In-Time) преобразует промежуточный код CIL в машинный код непосредственно во время выполнения программы, как правило, при первом вызове метода, и кэширует результат для последующих вызовов.

Начиная с .NET Core, JIT-компилятор получил ряд значительных улучшений, направленных на повышение производительности:

  • Профильно-ориентированная оптимизация (PGO) — технология, представленная в .NET 6 и включённая по умолчанию в .NET 8, собирает данные о наиболее часто выполняемых участках кода («горячих путях»). Эти данные используются для более агрессивных оптимизаций, таких как девиртуализация и встраивание (inlining)[25]. В .NET 9 PGO была расширена для оптимизации проверок типов.
  • On-Stack Replacement (OSR) — появившаяся в .NET 7 функция, которая позволяет «на лету» заменять код долго выполняющегося метода на более оптимизированную версию, сгенерированную с учётом данных PGO, не дожидаясь следующего вызова.
  • Оптимизация структур — в .NET 8 была внедрена скалярная замена агрегатов (Struct Promotion), позволяющая JIT-компилятору рассматривать поля структур как отдельные локальные переменные для более эффективной оптимизации. В .NET 10 компилятор научился размещать поля структур напрямую в регистрах процессора.
  • Поддержка векторных инструкций — в .NET 8 добавлена поддержка AVX-512, а в .NET 10 — AVX10.2[26], что значительно ускоряет параллельную обработку данных.
  • Деабстракция — в .NET 10 ключевым направлением стало снижение «цены абстракций» за счёт расширенного анализа выхода (Escape Analysis). Это позволяет размещать на стеке объекты, которые ранее всегда выделялись в куче, например, небольшие массивы и делегаты, что снижает нагрузку на сборщик мусора.

Помимо JIT-компиляции, современные версии .NET активно развивают технологию Ahead-of-Time (AOT)-компиляции, которая преобразует CIL в машинный код на этапе сборки приложения:

  • Crossgen2 — представленный в .NET 6 инструмент выполняет предварительную компиляцию для ускорения запуска приложения, но оставляет JIT-компилятору возможность дополнительно оптимизировать код во время выполнения (например, с помощью PGO).
  • Native AOT — технология, полноценно представленная в .NET 7 для консольных приложений и расширенная на ASP.NET Core в .NET 8[27]. Она создаёт полностью самодостаточный исполняемый файл без зависимости от JIT-компилятора и установленной среды .NET, что обеспечивает минимальное время запуска и меньшее потребление памяти.

Сборщик мусора (GC)

Сборщик мусора (англ. Garbage Collector, GC) — компонент CLR, отвечающий за автоматическое управление памятью. Он освобождает память, занятую объектами, которые больше не используются приложением. GC в .NET использует модель с поколениями (0, 1 и 2) для оптимизации сборки недолговечных объектов, а также отдельную кучу для больших объектов (англ. Large Object Heap, LOH). Поддерживаются различные режимы работы, включая Workstation (для клиентских приложений) и Server (для серверных нагрузок с высокой пропускной способностью)[28].

Начиная с .NET Core, сборщик мусора получил ряд ключевых архитектурных улучшений, направленных на повышение производительности и эффективности:

  • Регионы памяти — в .NET 7 для 64-битных систем был завершён переход от сегментной модели кучи к региональной. Регионы — более мелкие и гибкие единицы памяти, что является основой для будущих оптимизаций и позволяет более эффективно управлять памятью. Эта работа велась, в том числе, в .NET 6, где были сокращены паузы GC[29].
  • Динамическая адаптация (DATAS) — представленная в .NET 8 и включённая по умолчанию в .NET 9 функция, которая позволяет GC динамически настраивать потребление памяти в зависимости от реальных потребностей приложения, а не только от общего лимита памяти.
  • Куча для закреплённых объектов (англ. Pinned Object Heap) — добавленная в .NET 8 специальная область памяти для закреплённых объектов. Это помогает уменьшить фрагментацию основной кучи, которая возникает, когда GC не может перемещать закреплённые объекты.
  • Снижение нагрузки на GC — в .NET 9 JIT-компилятор научился размещать на стеке «упакованные» объекты (англ. boxed objects), которые ранее всегда выделялись в куче, что снижает частоту сборок мусора. В .NET 10 была расширена возможность размещения на стеке массивов и делегатов.
  • Сокращение пауз на ARM64 — в .NET 10 для архитектуры ARM64 была внедрена новая схема барьера записи, которая сокращает паузы «stop-the-world» на 8–20%[30].

Загрузчик сборок

Ищет, проверяет и загружает .dll/.exe-файлы по требованию, разрешая зависимости[31].

Менеджер типов (CTS)

Гарантирует типобезопасность и единое представление данных для всех .NET-языков[31].

Система безопасности

В современных версиях .NET (начиная с .NET Core) модель безопасности CLR была кардинально пересмотрена. В отличие от .NET Framework, среда выполнения больше не использует технологию Code Access Security (CAS) и связанную с ней модель Security Transparency для создания «песочниц» внутри процесса[32][33]. Эти механизмы были упразднены из-за их сложности, низкой эффективности и несовместимости с кроссплатформенной архитектурой[34].

Современный подход к безопасности предполагает, что весь код, выполняемый внутри одного процесса, является полностью доверенным. Изоляция и ограничение прав достигаются на уровне операционной системы с помощью таких технологий, как контейнеризация (например, Docker), виртуализация или запуск приложений от имени пользователей с ограниченными привилегиями[35][36].

Метаданные

Содержат описание типов и членов, используемое всеми компонентами среды выполнения[37].

Жизненный цикл выполнения кода

  1. Компиляция исходного кода в CIL и метаданные.
  2. Загрузка сборок в домен приложения.
  3. Верификация и проверки безопасности.
  4. JIT-компиляция методов.
  5. Исполнение нативного кода под управлением CLR.
  6. Сборка мусора и выгрузка ресурсов[6].

Управление памятью и сборка мусора

Управляемая куча делится на поколения 0, 1, 2 и кучу для больших объектов (англ. Large Object Heap). Сборщик мусора применяет копирующий алгоритм для молодых объектов и уплотнение для поколения 2 (англ. Generation 2), поддерживает фоновые сборки, финализаторы и слабые ссылки[38].

Начиная с .NET Core, сборщик мусора получил ряд ключевых архитектурных улучшений, направленных на повышение производительности и эффективности. Основные направления развития включают переход на региональную модель кучи для более гибкого управления памятью, внедрение механизмов динамической адаптации к нагрузке (DATAS), уменьшение фрагментации за счёт отдельных куч для специфических объектов и снижение нагрузки на GC путём размещения большего числа объектов на стеке. Подробные сведения об этих изменениях представлены в разделе Сборщик мусора (GC).

Безопасность кода и верификация

Модель безопасности CLR претерпела кардинальные изменения с переходом от .NET Framework к .NET Core. Старые механизмы, основанные на попытках создать «песочницу» внутри процесса, были упразднены в пользу изоляции на уровне операционной системы. Основные компоненты и их текущий статус:

  • Code Access Security (CAS) — устаревшая модель безопасности из .NET Framework, позволявшая создавать внутрипроцессные «песочницы» и ограничивать действия кода на основе его происхождения (например, из интернета или локальной сети). С выходом .NET Core от CAS полностью отказались из-за её сложности, низкой эффективности и несовместимости с кроссплатформенной архитектурой. Начиная с .NET 5, связанные с ней API помечены как устаревшие и больше не поддерживаются.
  • Security Transparency (прозрачность безопасности) — компонент CAS, который разделял код на уровни доверия (transparent, safe-critical, critical)[39]. Как и CAS, эта модель была упразднена в .NET Core, и связанные с ней атрибуты больше не оказывают никакого эффекта на выполнение кода[40].
  • Strong Name (строгое имя) — технология, обеспечивающая уникальную идентичность сборки (имя, версия, открытый ключ). В .NET Framework она также использовалась для защиты от подмены и размещения сборок в GAC[41]. В современных версиях .NET среда выполнения больше не проверяет криптографическую подпись строгого имени при загрузке, и технология считается устаревшей[42]. Её основное применение сегодня — предотвращение конфликтов имён и обеспечение обратной совместимости. Важно отметить, что строгие имена не являются механизмом безопасности для аутентификации кода; для этих целей используется Authenticode[43].
  • Верификатор IL — компонент CLR, который остаётся актуальным. Он проверяет корректность и типобезопасность промежуточного кода CIL перед его JIT-компиляцией, что является фундаментальным элементом безопасности платформы, предотвращая некорректный доступ к памяти[44].

Взаимодействие с языками и платформами .NET

Межъязыковая интероперабельность опирается на:

  • Common Type System (CTS);
  • Common Language Specification (CLS);
  • метаданные сборок, позволяющие вызывать компоненты, написанные на C#, F#, VB.NET и др[45].

Преимущества

  • автоматическое управление памятью;
  • единая модель безопасности;
  • межъязыковая совместимость;
  • оптимизации производительности через JIT;
  • минимизация «DLL Hell» за счёт строгих имён сборок[46].

Недостатки

  • Зависимость от платформы .NET. Хотя сама платформа является кроссплатформенной, приложение требует для запуска установленной среды выполнения (за исключением сборок Native AOT).
  • «Холодный старт». При первом запуске может наблюдаться задержка из-за JIT-компиляции кода. Этот недостаток частично или полностью устраняется с помощью технологий предварительной компиляции (Crossgen2 и Native AOT).
  • Ограниченный прямой доступ к низкоуровневым возможностям оборудования и операционной системы, что является характерной чертой управляемых сред.
  • Упразднение моделей безопасности .NET Framework. Механизмы для создания внутрипроцессных «песочниц», такие как Code Access Security (CAS) и Security Transparency, были полностью удалены в .NET Core и последующих версиях. Задачи по изоляции кода теперь решаются на уровне операционной системы, например, с помощью контейнеров.

Сферы применения

  • веб-приложения (ASP.NET Core);
  • настольные приложения (Windows Forms, WPF, .NET MAUI);
  • мобильные приложения (Xamarin, .NET MAUI);
  • облачные сервисы и микросервисы;
  • игровые проекты (движок Unity);
  • IoT-устройства[47].

Инструменты и средства разработки

  • IDE: Visual Studio, Visual Studio Code + OmniSharp, JetBrains Rider, MonoDevelop;
  • Командные утилиты: .NET CLI, MSBuild, NuGet, clrver.exe, dotnet-trace/dump/counters;
  • Отладка: встроенные отладчики Visual Studio и Rider, WinDbg + SOS;
  • Профилирование: Visual Studio Profiler, PerfView, dotTrace, dotMemory;
  • Декомпиляция: ILSpy, dnSpy, dotPeek, .NET Reflector;
  • Статический анализ и тестирование: ReSharper, NDepend, NUnit, BenchmarkDotNet[48].

Аналоги и альтернативы

  • JVM — виртуальная машина Java, выполняющая байт-код Java;
  • CoreCLR — кроссплатформенная реализация CLR для .NET 5+;
  • BEAM — виртуальная машина Erlang для распределённых систем[49];
  • V8 — JIT-движок JavaScript, используемый в Chrome и Node.js[50].

Примечания

  1. Exploring the History of Microsoft’s Headquarters in Redmond, Washington. Consumer Search. Дата обращения: 21 мая 2024.
  2. Common Language Runtime (CLR) overview. Microsoft Learn. Дата обращения: 21 мая 2024.
  3. Common Language Runtime (CLR) in C#. GeeksforGeeks. Дата обращения: 29 июля 2025.
  4. What is the Common Language Runtime (CLR)? TechTarget. Дата обращения: 29 июля 2025.
  5. CLR. DEV Community. Дата обращения: 29 июля 2025.
  6. 1 2 [medium.com](https://medium.com/@payton9609/clr-common-language-runtime-87a2e76555f6)
  7. [narod.ru](https://magister-stylus.narod.ru/net.html)
  8. Microsoft .NET: революция в программировании. itweek.ru. Дата обращения: 29 июля 2025.
  9. A Comprehensive History of the .NET Framework. Bocasay. Дата обращения: 29 июля 2025.
  10. .NET Framework 1.1. versionsof.net. Дата обращения: 29 июля 2025.
  11. .NET Versions: A Comprehensive Guide to History and Features (2025 Edition). ModLogix. Дата обращения: 29 июля 2025.
  12. Announcing .NET Framework 4.6. Microsoft. Дата обращения: 29 июля 2025.
  13. Revolutionizing Development: A Comprehensive Journey Through CLR and .NET. Medium. Дата обращения: 29 июля 2025.
  14. What's new in .NET 6. Microsoft Learn. Дата обращения: 29 июля 2025.
  15. Performance Improvements in .NET 6. Microsoft. Дата обращения: 29 июля 2025.
  16. Performance Improvements in .NET 7. Microsoft. Дата обращения: 29 июля 2025.
  17. Параметры конфигурации сборки мусора. Microsoft Learn. Дата обращения: 29 июля 2025.
  18. What's new in the .NET 8 runtime. Microsoft Learn. Дата обращения: 29 июля 2025.
  19. .NET 8: Top 10 New Features You Need to Know. NDepend. Дата обращения: 29 июля 2025.
  20. What's new in the .NET 9 runtime. Microsoft Learn. Дата обращения: 29 июля 2025.
  21. Что нового в C# 13 и .NET 9? Habr (9 октября 2024). Дата обращения: 29 июля 2025.
  22. Performance Improvements in .NET 10. Microsoft. Дата обращения: 29 июля 2025.
  23. What's new in the .NET 10 runtime. Microsoft Learn. Дата обращения: 29 июля 2025.
  24. .NET 10 Preview: Features, Breaking Changes, and Enhancements. abp.io. Дата обращения: 29 июля 2025.
  25. EgorBo. PGO for virtual/interface calls. Дата обращения: 29 июля 2025.
  26. What's new in .NET 10. Microsoft Learn. Дата обращения: 29 июля 2025.
  27. Performance improvements in ASP.NET Core 8. Microsoft. Дата обращения: 29 июля 2025.
  28. Основы сборки мусора. Microsoft Learn. Дата обращения: 29 июля 2025.
  29. dotnet 6 vs 4.8 GC stats. nietras.com (26 ноября 2021). Дата обращения: 29 июля 2025.
  30. The New Features and Enhancements in .NET 10, Part 2. CODE Magazine. Дата обращения: 29 июля 2025.
  31. 1 2 [geeksforgeeks.org](https://www.geeksforgeeks.org/architecture-of-common-language-runtime-clr/)
  32. Understanding Code Access Security (CAS) in the Microsoft .NET Framework. netizen.net. Дата обращения: 29 июля 2025.
  33. Code Access Security APIs are obsolete. Microsoft Learn. Дата обращения: 29 июля 2025.
  34. Разница между .NET Core и .NET Framework. run-dev.ru. Дата обращения: 29 июля 2025.
  35. Выбор между .NET 5+ и .NET Framework для серверных приложений. Microsoft Learn. Дата обращения: 29 июля 2025.
  36. Secure Coding Guidelines. Microsoft Learn. Дата обращения: 29 июля 2025.
  37. [c-sharpcorner.com](https://www.c-sharpcorner.com/UploadFile/9582c9/what-is-common-language-runtime-in-C-Sharp/)
  38. Как устроен сборщик мусора в .NET. Habr (10 апреля 2024). Дата обращения: 29 июля 2025.
  39. What’s New in Code Access Security in .NET Framework 4.0 – Part I. Simple Talk. Дата обращения: 29 июля 2025.
  40. SecurityTransparentAttribute Class. Microsoft Learn. Дата обращения: 29 июля 2025.
  41. Strong Names and Signing Assemblies in .NET. davidyardy.com. Дата обращения: 29 июля 2025.
  42. Strong naming for .NET libraries. Microsoft Learn. Дата обращения: 29 июля 2025.
  43. Enhanced Strong Naming. Microsoft Learn. Дата обращения: 29 июля 2025.
  44. .NET IL Emitting and Verification. acizmarik.com. Дата обращения: 29 июля 2025.
  45. [positiwise.com](https://positiwise.com/blog/advanced-cross-language-interoperability-in-clr)
  46. [geeksforgeeks.org](https://www.geeksforgeeks.org/c-sharp/common-language-runtime-clr-in-c-sharp/)
  47. [existek.com](https://existek.com/blog/what-is-net-used-for/)
  48. [sam-solutions.com](https://sam-solutions.com/blog/dot-net-development-tools/)
  49. [karmanov.su](https://karmanov.su/beam.html)
  50. [habr.com](https://habr.com/ru/companies/ruvds/articles/337460/)