Что такое clr
Перейти к содержимому

Что такое clr

Особенности работы CLR в .NET framework

Начиная изучать язык C# и .NEt Framework я ни как не мог понять, как же работает CLR. Я либо находил огромные статьи, которые не осилить за 1 вечер либо слишком краткое, скорее даже запутывающее описание процесса (как в книге Г. Шилдта).
Некоторое время назад я решил, что было бы неплохо собирать знания, полученные из книг, «фичи» и часто используемые приемы в одном месте. А то новая информация быстро оседает в голове, но также быстро забывается и спустя несколько недель приходится вновь рыться в сотнях и тысячах строк текста, чтобы найти ответ на вопрос. Читая очередную книгу по программированию, я делал краткие пометки самого важного, что мне показалось. Иногда описывал некоторый процесс понятным мне языком с придуманным примером и т.д. Я не претендую на абсолютную правильность излагаемого материала. Это всего лишь мое понимание процесса, с моими примерами и информацией, которую я посчитал ключевой для понимания Проработав некоторый материал, я решил сохранить это для всех тех, кому это может быть полезно. А кто уже знаком — тот просто освежит это в памяти.

Нужно отметить, что понятие «тип» это некоторое подобие класса в языке C#. Но т.к. .NET поддерживает не только C# но и другие языки, то используется понятие «тип», а не привычный «класс». Также данная статья предполагает, что читатель уже знаком с особенностями .Net и раскрывает особенности специфических вещей и процессов.

В качестве примера приведу текст программы, выводящий на экран возраст объекта:
исходный текст программы, чтобы было понятно:
using System;

namespace ConsoleApplication_Test_Csharp
public class SomeClass
int age;
public int GetAge()
age = 22;
return age;
>
>
public sealed class Program
<
public static void Main()
System. Console .Write( «My age is » );
SomeClass me = new SomeClass();
int myAge;
myAge = me.GetAge();
System. Console .WriteLine(myAge);
Console .ReadLine();
>

>
>

* This source code was highlighted with Source Code Highlighter .

И так приступим:

Что такое CLR?

CLR (Common language runtime) — общеязыковая исполняющая среда. Она обеспечивает интеграцию языков и позволяет объектам благодаря стандартному набору типов и метаданным), созданным на одном языке, быть «равноправными гражданами» кода, написанного на другом.

CLR

Другими словами CLR этот тот самый механизм, который позволяет программе выполняться в нужном нам порядке, вызывая функции, управляя данными. И все это для разных языков (c#, VisualBasic, Fortran). Да, CLR действительно управляет процессом выполнения команд (машинного кода, если хотите) и решает, какой кусок кода (функцию) от куда взять и куда подставить прямо в момент работы программы. Процесс компиляции представлен на рисунке:

IL

IL (Intermediate Language) — код на специальном языке, напоминающим ассемблер, но написанном для .NET. В него преобразуется код из других языков верхнего уровня (c#, VisualBasic). Вот тогда-то и пропадает зависимость от выбранного языка. Ведь все преобразуется в IL (правда тут есть оговорки соответствия общей языковой спецификации CLS, что не входит в рамки данной статьи)
Вот как он выглядит для функции SomeClass::GetAge()

Компилятор, помимо ассемблера IL создает полные метаданные.

Метаданные — набор из таблиц данных, описывающих то, что определено в модуле. Также есть таблицы, указывающие на что ссылается управляемый модуль (например, импортируемые типы и числа). Они расширяют возможности таких технологий как библиотеки типов и файлы языка описания интерфейсов (IDL). Метаданные всегда связаны с файлом с IL кодом, фактически они встроены в *.exe или *.dll.
Таким образом метаданные это таблицы, в которых есть поля, говорящие о том, что такой-то метод находится в таком-то файле и принадлежит такому-то типу(классу).
Вот как выглядят метаданные для моего примера (таблицы метаданных просто преобразованы в понятный вид с помощью дизассемблера ILdasm.exe. На самом деле это часть *.exe файла программы:

metadata

TypeDef — это запись, для каждого типа, определенного в модуле
К примеру TypeDef #1 описывает класс SomeClass и показывает поле Field #1 с именем Field Name: age, метод MethodName: GetAge и конструктор MethodName: .ctor. Запись TypeDef #2 описывает класс Program.

Разобравшись с основными понятиями, давайте посмотрим из чего же состоит тот самый управляемый модуль (или просто наш файл ConsoleApplication_Test_Csharp.exe, который выполняет вывод на экран возраста объекта):

Заголовок показывает на каком типе процессора будет выполняться программа. РЕ32 (для 32 и 64 битных ОС) или РЕ32+ (только для 64 битных ОС)
Заголовок CLR — содержит информацию, превращающую этот модуль в управляемый (флаги, версия CLR, точки входа в Main())
Метаданные — 2 вида таблиц метаданных:
1) определенные в исходном коде типы и члены
2) типы и члены, имеющие ссылки в исходном коде.
Код IL — Код, создаваемый компилятором при компиляции кода на C#. Затем IL преобразуется в процессорные команды (0001 0011 1101… ) при помощи CLR (а точнее JIT)

Работа JIT

И так, что же происходит, когда запускается впервые программа?
Сперва происходит анализ заголовка, чтобы узнать какой процесс запустить (32 или 64 разрядный). Затем загружается выбранная версия файла MSCorEE.dll ( C:\Windows\System32\MSCorEE.dll для 32разрядных процессоров)
После чего вызывается метод, расположенный MSCorEE.dll, который и инициализирует CLR, сборки и точку входа функции Main() нашей программы.

static void Main()
System. Console .WriteLine( «Hello » );
System. Console .WriteLine( «Goodbye» );
>

* This source code was highlighted with Source Code Highlighter .

Для выполнения какого-либо метода, например System.Console.WriteLine(«Hello „), IL должен быть преобразован в машинные команды (те самые нули и единицы) Этим занимается Jiter или just-in-time compiler.

Сперва, перед выполнением Main() среда CLR находит все объявленные типы (например тип Console).
Затем определяет методы, объединяя их в записи внутри единой “структуры» (по одному методу определенному в типе Console).
Записи содержат адреса, по которым можно найти реализации методов (т.е. те преобразования, которые выполняет метод).

Jit

При первом обращение к функции WriteLine вызывается JiT-compiler.
JiTer ‘у известны вызываемый метод и тип, которым определен этот метод.
JiTer ищет в метаданных соответствующей сборки — реализацию кода метода (код реализации метода WriteLine(string str) ).
Затем, он проверяет и компилирует IL в машинный код (собственные команды), сохраняя его в динамической памяти.
После JIT Compiler возвращается к внутренней «структуре» данных типа (Console) и заменяет адрес вызываемого метода, на адрес блока памяти с исполняемыми процессорными командами.
После этого метод Main() обращается к методу WriteLine(string str) повторно. Т.к. код уже скомпилирован, обращение производится минуя JiT Compiler. Выполнив метод WriteLine(string str) управление возвращается методу Main().

Из описания следует, что «медленно» работает функция только в момент первого вызова, когда JIT переводит IL код в инструкции процессора. Во всех остальных случаях код уже находится в памяти и подставляется как оптимизированный для данного процессора. Однако если будет запущена еще одна программа в другом процессе, то Jiter будет вызван снова для того же метода. Для приложений выполняемых в х86 среде JIT генерируется 32-разрядные инструкции, в х64 или IA64 средах — соответственно 64-разрядные.

Оптимизация кода. Управляемый и неуправляемый код

IL может быть оптимизирован, т.е. из него будут удалены IL — команды NOP (пустая команда). Для этого при компиляции нужно добавить параметры

Debug версия собирается с параметрами: /optimize -, /debug: full
Release версия собирается с параметрами: /optimize +, /debug: pdbonly

Чем же отличается управляемый код от неуправляемого?

Неуправляемый код компилируется для конкретного процессора и при вызове просто исполняется.

В управляемой среде компиляция производится в 2 этапа:

1) компилятор переводит C# код в IL
2) для исполнения нужно перевести IL код в машинный код процессора, что требует доп. динамической памяти и времени (как раз та самая работа JIT).

Взаимодействие с неуправляемым кодом:

— управляемый код может вызывать направляемую функцию из DLL посредствам P/Invoke (например CreateSemaphore из Kernel32.dll).
— управляемый код может использовать существующий COM-компонент (сервер).
— неуправляемый код может использовать управляемый тип (сервер). Можно реализовать COM — компоненты в управляемой среде и тогда не нужно вести подсчет ссылок интерфейсов.

Параметр /clr позволяет скомпилировать Visual С++ код в управляемые IL методы (кроме когда, содержащего команды с ассемблерными вставками ( __asm ), переменное число аргументов или встроенные процедуры ( __enable, _RetrurAddress )). Если этого сделать не получится, то код скомпилируется в стандартные х86 команды. Данные в случае IL кода не являются управляемыми (метаданные не создаются) и не отслеживаются сборщиком мусора (это касается С++ кода).

Система типов

В дополнение хочу рассказать о системе типов CTS, принятой Microsoft.

CTS (Common Type System) — общая система типов в CLR (тип, по-видимому — это аналог класса C#). Это — стандарт, признанный ECMA который описывает определение типов и их поведение. Также определяет правила наследования, виртуальных методов, времени жизни объектов. После регистрации ECMA стандарт получил название CLI ( Common Language Infrastructure)

— CTS поддерживает только единичное наследование (в отличие от С++)
— Все типы наследуются от System.Object (Object — имя типа, корень все остальных типов, System — пространство имен)

По спецификации CTS любой тип содержит 0 или более членов.

Поле — переменная, часть состояния объекта. Идентифицируются по имени и типу.
Метод — функция, выполняющая действие над объектом. Имеет имя, сигнатуру(число параметров, последовательность, типы параметров, возвр. значение функции) и модификаторы.
Свойство — в реализации выглядит как метод (get/set) а для вызывающей стороны как поле ( = ). Свойства позволяют типу, в котором они реализованы, проверить входные параметры и состояние объекта.
Событие — обеспечивает механизм взаимного уведомления объектов.

Public — метод доступен любому коду из любой сборки
Private — методы вызывается только внутри типа
Family (protected) — метод вызывается производными типами независимо от сборки
Assembly (internal) — метод вызывается любым кодом из той же сборки
Family or Assembly
(protected internal) — метод вызывается производными типами из любой сборки и + любыми типами из той же сборки.

CLS (Common Language Specification) — спецификации выпущенная Майкрософт. Она описывает минимальный набор возможностей, которые должны реализовать производители компиляторов, чтобы их продукты работали в CLR. CLR/CTS поддерживает больше возможностей, определенных CLS. Ассемблер IL поддерживает полный набор функций CLR/CTS. Языки (C#, Visual Basic) поддерживает часть возможностей CLR/CTS (в т.ч. минимум от CLS).
Пример на рисунке

CLS

Пример проверки на соответствие CLS

Атрибут [assembly: CLSCompliant(true)] заставляет компилятор обнаруживать любые доступные извне типы, содержащие конструкции, недопустимые в других языках.

  1. using System;
  2. [assembly: CLSCompliant( true )]
  3. namespace SomeLibrary
  4. // возникает предупреждение поскольку тип открытый
  5. public sealed class SomeLibraryType
  6. // тип, возвращаемый функцией не соответсвует CLS
  7. public UInt32 Abc()
  8. // идентификатор abc() отличается от предыдущего, только если
  9. // не выдерживается соответсвие
  10. public void abc()
  11. // ошибки нет, метод закрытый
  12. private UInt32 ABC()
  13. >
  14. >

Первое предупреждение: UInt32 Abc() возвращает целочисленное целое без знака. Visaul Basic, например, не работает с такими значениями.
Второе предупрждение: два открытых метода Abc() и abc() — одиноквые и отличаются лишь регистром букв и возвращаемым типом. VisualBasic не может вызывать оба метода.

Убрав public и оставив только sealed class SomeLibraryType оба предупреждения исчезнут. Так как SomeLibraryType по-умолчанию будет internal и не будет виден извне сборки.

P.S. Статья основана на материалах из книги Дж. Рихтера «CLR via C#. Программирование на платформе Microsoft .NET Framework 2.0 на языке C#»

Что такое clr

Поиск

Исполняющая среда CLR (Common Language Runtime) в C# . JIT (Just-In-Time) компилятор.
Посмотрели 13232 раз(а)
Исполняющая среда CLR (Common Language Runtime) в C# . JIT (Just-In-Time) компилятор.
последнее обновление: 21 июня 2023

CLR это исполняющая среда для выполнения IL (промежуточного кода).
CLR создает объекты в памяти, вызывает методы, удаляет объекты из памяти.
CLR является одним из основных компонентов в .NET Framework .

Выполнение C# приложения исполнительной средой CLR

Когда мы запускам C# приложение, тоесть открываем exe файл, тогда начинает работать CLR .
CLR исполняет каждую строчку IL кода в 2 шага.
IL (промежуточный код) находится в сборке (в exe файлe) .

IL (промежуточный код) компилируется в комманды процессора ( 0001 0011 1101… ). Этим занимается JIT компилятор в CLR среде.

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

В Microsoft аргументируют , что такой процесс более эффективен, чем компиляция всего приложения при запуске, поскольку высока вероятность того, что крупные фрагменты кода приложения на самом деле не будут выполняться при каждом запуске.

Common Language Runtime

Common Language Runtime (англ. CLRобщеязыковая исполняющая среда) — виртуальная машина, интерпретирующая и исполняющая код на языке CIL, в который компилируются программы, написанные, в частности, на .NET-совместимых языках программирования (C#, Managed C++, Visual Basic .NET, Visual J# и т. п.); компонент пакета Microsoft .NET Framework.

Среда CLR является реализацией спецификации CLI (англ. Common Language Infrastructure ), спецификации общеязыковой инфраструктуры компании Microsoft.

Механизм работы

CLR интерпретирует и исполняет код на языке CIL (реализация компиляции которого компанией Microsoft называется MSIL), а также предоставляет MSIL-программам (а следовательно, и программам, написанным на языках высокого уровня, поддерживающих .NET Framework) доступ к библиотекам классов .NET Framework, или так называемой .NET FCL (англ. Framework Class Library ).

См. также

  • Ngen — программа для компиляции сборок на IL в машинный код

Литература

  • Джеффри Рихтер CLR via C#. Программирование на платформе .NET Framework 2.0 на языке C# = CLR via C#. — СПб. : Питер, 2008. — ISBN 978-5-7502-0348-2, 978-5-91180-303-2
.NET Framework
Архитектура Base Class Library • Common Language Infrastructure • .NET assembly • метаданные • COM Interop
Инфраструктура Common Language Runtime • Common Type System • Common Intermediate Language • Virtual Execution System • Dynamic Language Runtime
Языки Microsoft C# • Cω • Visual Basic .NET • C++/CLI (Managed) • Visual J# • JScript .NET • Windows PowerShell • IronPython • IronRuby • F# • Spec# • Sing#
Другие языки A# • Boo • IronLisp • L# • Nemerle • P# • PascalABC.NET • PHP • Scala • Cobra • Delphi Prism
Windows Foundations Presentation • Communication • Workflow
Компоненты ADO.NET (Entity Framework · Data Services) · ASP.NET (AJAX · MVC · Dynamic Data) · .NET Remoting · Language Integrated Query · Windows CardSpace · Windows Forms · XAML · ClickOnce · Dynamic Language Runtime · Parallel FX Library (PLINQ · TPL)
Реализации DotGNU • Mono • .NET Compact Framework (Xbox 360) • .NET Micro Framework • Portable.NET • XNA Framework • Silverlight • Shared Source Common Language Infrastructure
Сравнения C# и Java • C# и Visual Basic .NET
Будущие технологии Acropolis • Jasper
  • .NET Framework

Wikimedia Foundation . 2010 .

Что такое clr

Microsoft .NET – платформа или среда, обеспечивающая выполнение программного кода.

.NET Framework – инфраструктура платформы Microsoft .NET, определяющая особенности разработки и выполнения программного кода на данной платформе. Предполагает наличие средств организации взаимодействия с операционной системой и прикладными программами. Включает следующие основные компоненты: Common Language Runtime (CLR) и .NET Framework Class Library (.NET FCL).

CLS (Common Language Specification) – общая спецификация языков программирования. Это набор конструкций и ограничений, которые являются руководством для создателей библиотек и компиляторов в среде .NET Framework. Библиотеки, построенные в соответствии с CLS, могут быть использованы из любого языка программирования, поддерживающего CLS. Языки, соответствующие CLS (к их числу относятся языки Visual C#, Visual Basic, Visual C++), могут интегрироваться друг с другом. CLS – это основа межъязыкового взаимодействия в рамках платформы Microsoft .NET.

CLR (Common Language Runtime) – Среда Времени Выполнения или Виртуальная Машина. Обеспечивает выполнение сборки. Основной компонент .NET Framework. Под Виртуальной Машиной понимают абстракцию инкапсулированной (обособленной) управляемой операционной системы высокого уровня, которая обеспечивает выполнение (управляемого) программного кода.

Управляемый код – программный код, который при своем выполнении способен использовать службы, предоставляемые CLR. Соответственно, неуправляемый код подобной способностью не обладает. Об особенностях управляемого кода можно судить по перечню задач, решение которых возлагается на CLR:

  • Управление кодом (загрузка и выполнение).
  • Управление памятью при размещении объектов.
  • Изоляция памяти приложений.
  • Проверка безопасности кода.
  • Преобразование промежуточного языка в машинный код.
  • Доступ к метаданным (расширенная информация о типах).
  • Обработка исключений, включая межъязыковые исключения.
  • Взаимодействие между управляемым и неуправляемым кодами (в том числе и COM-объектами).
  • Поддержка сервисов для разработки (профилирование, отладка и т.д.).

Короче, CLR – это набор служб, необходимых для выполнения управляемого кода.

Сама CLR состоит из двух главных компонентов: ядра (mscoree.dll) и библиотеки базовых классов (mscorlib.dll). Наличие этих файлов на диске – верный признак того, что на компьютере, по крайней мере, была предпринята попытка установки платформы .NET.

Ядро среды выполнения реализовано в виде библиотеки mscoree.dll. При компоновке сборки в нее встраивается специальная информация, которая при запуске приложения (EXE) или при загрузке библиотеки (обращение к DLL из неуправляемого модуля – вызов функции LoadLibrary для загрузки управляемой сборки) приводит к загрузке и инициализации CLR. После загрузки CLR в адресное пространство процесса, ядро среды выполнения производит следующие действия:

  • находит расположение сборки;
  • загружает сборку в память;
  • производит анализ содержимого сборки (выявляет классы, структуры, интерфейсы);
  • производит анализ метаданных;
  • обеспечивает компиляцию кода на промежуточном языке (IL) в платформозависимые инструкции (ассемблерный код);
  • выполняет проверки, связанные с обеспечением безопасности;
  • используя основной поток приложения, передает управление преобразованному в команды процессора фрагменту кода сборки.

FCL (.NET Framework Class Library) – соответствующая CLS-спецификации объектно-ориентированная библиотека классов, интерфейсов и системы типов (типов-значений), которые включаются в состав платформы Microsoft .NET.

Эта библиотека обеспечивает доступ к функциональным возможностям системы и предназначена служить основой при разработке .NET-приложений, компонент, элементов управления.

.NET библиотека классов является вторым компонентом CLR.

.NET FCL могут использовать все .NET-приложения, независимо от назначения архитектуры используемого при разработке языка программирования, и в частности:

  • встроенные (элементарные) типы, представленные в виде классов (на платформе .NET все построено на структурах или классах);
  • классы для разработки графического пользовательского интерфейса (Windows Forms);
  • классы для разработки web-приложений и web-служб на основе технологии ASP.NET (Web Forms);
  • классы для разработки XML и Internet-протоколов (FTP, HTTP, SMTP, SOAP);
  • классы для разработки приложений, работающих с базами данных (ADO .NET) и многое другое.

.NET-приложение – приложение, разработанное для выполнения на платформе Microsoft .NET. Реализуется на языках программирования, соответствующих CLS.

MSIL (Microsoft Intermediate Language) – промежуточный язык платформы Microsoft .NET. Исходные тексты программ для .NET-приложений пишутся на языках программирования, соответствующих спецификации CLS. Для таких языков может быть построен преобразователь в MSIL. Таким образом, программы на этих языках могут транслироваться в промежуточный код на MSIL. Благодаря соответствию CLS, в результате трансляции программного кода, написанного на разных языках, получается совместимый IL-код.

Фактически MSIL является ассемблером виртуального процессора.

МЕТАДАННЫЕ – при преобразовании программного кода в MSIL также формируется блок МЕТАДАННЫХ, который содержит информацию о данных, используемых в программе. Фактически это наборы таблиц, которые включают в себя информацию о типах данных, определяемых в модуле (о типах данных, на которые ссылается данный модуль). Ранее такая информация сохранялась отдельно. Например, приложение могло включать информацию об интерфейсах, которая описывалась на Interface Definition Language (IDL). Теперь метаданные являются частью управляемого модуля.

В частности, метаданные используются для:

  • сохранения информации о типах. При компиляции теперь не требуются заголовочные и библиотечные файлы. Всю необходимую информацию компилятор читает непосредственно из управляемых модулей;
  • верификации кода в процессе выполнения модуля;
  • управления динамической памятью (освобождение памяти) в процессе выполнения модуля;
  • обеспечения динамической подсказки (IntelliSence) при разработке программы стандартными инструментальными средствами (Microsoft Visual Studio .NET) на основе метаданных.

Языки, для которых реализован перевод на MSIL:

  • Visual Basic,
  • Visual C++,
  • Visual C# 2.0,

и еще много других языков.

Исполняемый модуль – независимо от компилятора (и входного языка) результатом трансляции .NET-приложения является управляемый исполняемый модуль (управляемый модуль). Это стандартный переносимый исполняемый (PE – Portable Executable) файл Windows.

Элементы управляемого модуля представлены в таблице.

Заголовок PE Показывает тип файла (например, DLL), содержит временную метку (время сборки файла), содержит сведения о выполняемом коде
Заголовок CLR Содержит информацию для среды выполнения модуля (версию требуемой среды исполнения, характеристики метаданных, ресурсов и т.д.). Собственно, эта информация делает модуль управляемым
Метаданные Таблицы метаданных: 1) типы, определенные в исходном коде; 2) типы, на которые имеются в коде ссылки
IL Собственно код, который создается компилятором при компиляции исходного кода. На основе IL в среде выполнения впоследствии формируется множество команд процессора

Управляемый модуль содержит управляемый код.

Управляемый код – это код, который выполняется в среде CLR. Код строится на основе объявляемых в исходном модуле структур и классов, содержащих объявления методов. Управляемому коду должен соответствовать определенный уровень информации (метаданных) для среды выполнения. Код C#, Visual Basic, и JScript является управляемым по умолчанию. Код Visual C++ не является управляемым по умолчанию, но компилятор может создавать управляемый код, для этого нужно указать аргумент в командной строке(/CLR). Одной из особенностей управляемого кода является наличие механизмов, которые позволяют работать с управляемыми данными.

Управляемые данные – объекты, которые в ходе выполнения кода модуля размещаются в управляемой памяти (в управляемой куче) и уничтожаются сборщиком мусора CLR. Данные C#, Visual Basic и JScript .NET являются управляемыми по умолчанию. Данные C# также могут быть помечены как неуправляемые.

Сборка (Assembly) – базовый строительный блок приложения в .NET Framework. Управляемые модули объединяются в сборки. Сборка является логической группировкой одного или нескольких управляемых модулей или файлов ресурсов. Управляемые модули в составе сборок исполняются в Среде Времени Выполнения (CLR). Сборка может быть либо исполняемым приложением (при этом она размещается в файле с расширением .exe), либо библиотечным модулем (в файле с расширением .dll). При этом ничего общего с обычными (старого образца!) исполняемыми приложениями и библиотечными модулями сборка не имеет.

Декларация сборки (Manifest) – составная часть сборки. Это еще один набор таблиц метаданных, который:

  • идентифицирует сборку в виде текстового имени, ее версию, культуру и цифровую сигнатуру (если сборка распределяется среди приложений);
  • определяет входящие в состав файлы (по имени и хэшу);
  • указывает типы и ресурсы, существующие в сборке, включая описание тех, которые экспортируются из сборки;
  • перечисляет зависимости от других сборок;
  • указывает набор прав, необходимых сборке для корректной работы.

Эта информация используется в период выполнения для поддержки корректной работы приложения.

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

В среде CLR допускается совместная работа и взаимодействие компонентов программного обеспечения, реализованных на различных языках программирования.

На основе ранее сформированного блока метаданных CLR обеспечивает эффективное взаимодействие выполняемых .NET-приложений.

Для CLR все сборки одинаковы, независимо от того, на каких языках программирования они были написаны. Главное – это чтобы они соответствовали CLS. Фактически CLR разрушает границы языков программирования (cross-language interoperability). Таким образом, благодаря CLS и CTS, .NET-приложения оказываются приложениями на MSIL (IL).

CLR берет на себя решение многих проблем, которые традиционно находились в зоне особого внимания разработчиков приложений. К числу функций, выполняемых CLR, относятся:

  • Проверка и динамическая (JIT) компиляция MSIL-кода в команды процессора.
  • Управление памятью, процессами и потоками.
  • Организация взаимодействия процессов.
  • Решение проблем безопасности (в рамках существующей в системе политики безопасности).

Структура среды выполнения CLR (основные функциональные элементы среды) представлена на рисунке.

Строгий контроль типов, в частности, предполагает проверку соответствия типа объекта диапазону значений, которые могут быть присвоены данному объекту.

Защита .NET (безопасность) строится поверх системы защиты операционной системы компьютера. Она не дает пользователю или коду делать то, что делать не позволено, и накладывает ограничения на выполнение кода. Например, можно запретить доступ некоторым секциям кода к определенным файлам.

Функциональные блоки CLR Code Manager и Garbage Collector работают совместно: Code Manager обеспечивает размещение объектов в управляемой памяти, Garbage Collector – освобождает управляемую память.

Exception Manager включает следующие компоненты:

  • finally handler (обеспечивает передачу управления в блок finally);
  • fault handler (включается при возникновении исключения);
  • type-filtered handler (обеспечивает выполнение кода соответствующего блока обработки исключения);
  • user-filtered handler (выбор альтернативного блока исключения).

Ниже представлена схема выполнения .NET-приложения в среде CLR.

AppDomain (домен приложения) – это логический контейнер сборок, который используется для изоляции приложения в рамках адресного пространства процесса. Код, выполняемый в CLR (CLR-процесс), отделен от других процессов, выполняемых на компьютере в это же самое время. Обычный процесс запускается системой в рамках специально выделяемого процессу адресного пространства. CLR предоставляет возможность выполнения множества управляемых приложений в одном процессе. Каждое управляемое приложение связывается с собственным доменом приложения (сокращенно AppDomain). Все объекты, создаваемые приложением, создаются в рамках определенного домена приложения. Несколько доменов приложений могут существовать в одном процессе операционной системы. CLR изолирует приложения, управляя памятью в рамках домена приложения. В приложении, помимо основного домена, может быть создано несколько дополнительных доменов.

  • Домены изолированы друг от друга. Объекты, созданные в рамках одного домена, недоступны из другого домена.
  • CLR способна выгружать домены вместе со всеми сборками, связанными с этими доменами.
  • Возможна дополнительная конфигурация и защита доменов.
  • Для обмена данными между доменами реализован специальный механизм безопасного доступа (маршалинг).
  • В .NET Framework разработана собственная компонентная модель, элементами которой являются .NET-сборки (.NET-assembly), а для прямой и обратной совместимости с моделью COM/COM+ в CLR встроены механизмы (COM Interop), обеспечивающие доступ к COM-объектам по правилам .NET и к .NET-сборкам — по правилам COM. При этом для .NET-приложений не требуется регистрации компонентов в системном реестре Windows.

GAC (Global Assembly Cache – Общий кэш сборок). Для выполнения .NET-приложения достаточно разместить относящиеся к данному приложению сборки в одном каталоге. Если при этом сборка может быть использована в нескольких приложениях, то она размещается и регистрируется с помощью специальной утилиты в GAC.

CTS – Common Type System (Стандартная Система Типов). Поддерживается всеми языками платформы. В силу того, что .NET основана на парадигме ООП, речь здесь идет об элементарных типах, классах, структурах, интерфейсах, делегатах и перечислениях. Common Type System является важной частью среды выполнения, определяет структуру синтаксических конструкций, способы объявления, использования и применения общих типов среды выполнения. В CTS сосредоточена основная информация о системе общих предопределенных типов, об их использовании и управлении (правилах преобразования значений). CTS играет важную роль в деле интеграции разноязыких управляемых приложений.

Пространство имен – это способ организации системы типов в единую группу. В рамках .NET существует единая (общеязыковая) библиотека базовых классов. Концепция пространства имен обеспечивает эффективную организацию и навигацию по этой библиотеке. Вне зависимости от языка программирования, доступ к определенным классам обеспечивается за счет их группировки в рамках общих пространств имен.

System
System.Data Классы для обращения к базам данных
System.Data.Common
System.Data.OleDb
System.Data.SqlClient
System.Collections Классы для работы с контейнерными объектами
System.Diagnostics Классы для трассировки и отладки кода
System.Drawing Классы графической поддержки
System.Drawing.Drawing2D
System.Drawing.Printing
System.IO Поддержка ввода/вывода
System.Net Поддержка передачи данных по сетям
System.Reflection Работа с пользовательскими типами во время выполнения приложения
System.Reflection.Emit
System.Runtime.InteropServices Поддержка взаимодействия с «обычным кодом» – DLL, COM-серверы, удаленный доступ
System.Runtime.Remoting
System.Security Криптография, разрешения
System.Threading Работа с потоками
System.Web Работа с web-приложениями

Выполнение неуправляемых исполняемых модулей (обычные Windows-приложения) обеспечивается непосредственно системой Windows. Неуправляемые модули выполняются в среде Windows как «простые» процессы. Процесс характеризуется замкнутым адресным пространством. При этом необходимая для выполнения программы информация (данные) размещается в различных областях адресного пространства процесса, которые называются стеком и кучей. Эти области имеют различное назначение и механизмы управления.

Информация в стеке и куче представляется в виде последовательностей битов с четко определенными свойствами. Такие последовательности называются объектами. Множество неизменяемых свойств, которые могут служить для классификации различных объектов (количество байтов последовательности, формат представления информации в последовательности, операции, определенные над объектом), задают тип объекта.

Таким образом, при выполнении программы в стеке и куче размещаются объекты различных типов.

В стеке размещается информация, необходимая для выполнения программного кода (реализация механизма вызова функций, поддержка операторов управления, сохранение значений локальных переменных). Основным механизмом управления стеком является указатель стека. Освобождение стека происходит в результате перемещения указателя стека, которое связано с выполнением операторов программы.

В куче размещаются используемые в программе данные. Они структурированы и представлены объектами различных типов. Размещение объектов в куче происходит в результате выполнения специального оператора new. Основным механизмом управления кучи является сборщик мусора (Garbage Collector).

Ссылкой (ссылкой на объект) называется объект, который определен на множестве значений, представленных адресами оперативной памяти в рамках процесса. Если значением ссылки является адрес конкретного объекта, ссылка считается определенной. Ссылка на объект не определена, если ее значение не соответствует адресу какого-либо объекта. Неопределенное значение ссылки в программе кодируется специальным обозначением (null). Особых ограничений на месторасположение ссылки не существует. Ссылка может располагаться как в стеке, так и в куче.

Сборка мусора – механизм, позволяющий CLR определить, когда объект становится недоступен в управляемой памяти программы. При сборке мусора управляемая память освобождается. Для разработчика приложения наличие механизма сборки мусора означает, что он больше не должен заботиться об освобождении памяти. Однако это может потребовать изменения в стиле программирования, например, особое внимание следует уделять процедуре освобождения системных ресурсов. Необходимо реализовать методы, освобождающие системные ресурсы, находящиеся под управлением приложения.

Более подробные сведения можно найти на сайте Марченко А.Л. Введение в программирование на C# 2.0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *