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

Представим, что у нас есть процесс Microsoft Windows с загруженной в него исполняющей средой CLR. У процесса может быть много потоков. После создания потоку выделяется стек размером в 1 Мбайт. Выделенная память используется для передачи параметров в методы и хранения определенных в пределах методов локальных переменных.

Допустим, есть следующие два определения классов:

internal class Employee {

`public Int32 GetYearsEmployed () { ... }`

`public virtual String GetProgressReport () { ... }`

`public static Employee Lookup(String name) { ... }`

}

internal sealed class Manager : Employee {

public override String GenProgressReport() { ... }

}

Процесс Windows запустился, в него загружена среда CLR, инициализирована управляемая куча, и создан поток (с его 1 Мбайт памяти в стеке). Поток уже выполняет какой-то код, из которого вызывается метод M3 . Метод M3 содержит код, продемонстрирующий, как работает CLR; вряд ли вы будете включать такой код в свои приложения, потому что он, в сущности, не делает ничего полезного.

void M3(){
    Employee e;
    Int32 year;
    e = new Manager();
    e = Employee.LookUp("Joe");
    year = e.GetYearsEmployed();
    e.GetProgressReport();
}

В процессе преобразования IL-кода метода М3 в машинные команды JIT-компилятор выявляет все типы, на которые есть ссылки в M3, — это типы Employee, Int32, Manager и String (из-за наличия строки "Joe"). На данном этапе CLR обеспечивает загрузку в домен приложений всех сборок, в которых определены все эти типы. Затем, используя метаданные сборки, CLR получает информацию о типах и создает структуры данных, собственно и представляющие эти типы. Структуры данных для объектов-типов Employee и Manager показаны на рис. 4.7. Поскольку до вызова M3 поток уже выполнил какой-то код, для простоты допустим, что объекты-типы Int32 и String уже созданы (что вполне возможно, так как это часто используемые типы), поэтому они не показаны на рисунке. После того как среда CLR создаст все необходимые для метода объекты-типы и откомпилирует код метода M3, она приступает к выполнению машинного кода M3. При выполнении входного кода M3 в стеке потока выделяется память для локальных переменных (рис. 4.8). В частности, CLR автоматически инициализирует все локальные переменные значением null или 0 (нулем) — это делается в рамках выполнения входного кода метода. Однако при попытке обращения к локальной переменной, неявно инициализированной в вашем коде, компилятор С# выдаст сообщение об ошибке Use of unassigned local variable (использование неинициализированной локальной переменной).

Все объекты в куче содержат два дополнительных члена: указатель на объект-тип и индекс блока синхронизации.

Объект-тип - это указатель на тип объекта. Он недоступен программисту напрямую без всяческих колдунств, поскольку предназначен для самой CLR

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

Далее будет выполнен остальной код метода путём создания объектов, вызова методов и прочего, о чём можно подробнее прочитать в самой книге (стр. 135)

results matching ""

    No results matching ""