Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 сем Инфа готово.docx
Скачиваний:
24
Добавлен:
04.06.2015
Размер:
255.66 Кб
Скачать

Вопрос 4. Компиляция и выполнение приложений на платформе Microsoft .Net.

Все CLR-совместимые компиляторы вместо этого генерируют IL-код, который также называется управляемым модулем, потому что CLR управляет его жизненным циклом и выполнением. Рассмотрим составные части управляемого модуля:

Заголовок PE32 или PE32+: Файл с заголовком в формате PE32 может выполняться в 32- или 64-разрядной ОС, а с заголовком PE32+ только в 64-разрядной ОС. Заголовок показывает тип файла: GUI, CUI или DLL, он также имеет временную метку, показывающую, когда файл был собран. Для модулей, содержащих только IL-код, основной объем информации в РЕ-заголовке игнорируется, Для модулей, содержащих процессорный код, этот заголовок содержит сведения о процессорном коде.

Заголовок CLR: Содержит информацию, которая превращает этот модуль в управляемый. Заголовок включает нужную версию СLR, некоторые флаги, метку метаданных, точки входа в управляемый модуль (метод Main), месторасположение и размер метаданных модуля, ресурсов и т.д.

Метаданные - это набор таблиц данных, описывающих то, что определено в модуле. Есть два основных вида таблиц: описывающие типы и члены, определенные в вашем исходном коде, и описывающие типы и члены, на которые имеются ссылки в вашем исходном коде. Метаданные служат многим целям:

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

2)при компиляции IL-кода в машинный код CLR выполняет верификацию (проверку "безопасности" выполнения кода) используя метаданные, например, нужное ли число параметров передается методу, корректны ли их типы, правильно ли используется возвращаемое значение и т.д.

3)позволяют сборщику мусора отслеживать жизненный цикл объектов и т.д.

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

По умолчанию CLR-совместимые компиляторы генерируют управляемый код, безопасность выполнения которого поддается проверке средой CLR. Вместе с тем возможно разрабатывать неуправляемый или "небезопасный" код, которому разрешается работать непосредственно с адресами памяти и управлять байтами в этих адресах. Эта возможность, обычно полезна при взаимодействии с неуправляемым кодом или при необходимости добиться максимальной производительности при выполнении критически важных алгоритмов. Однако использовать неуправляемый код довольно рискованно, т.к. он способен разрушить существующие структуры данных.

Чтобы понять принцип выполнения программы в среде CLR рассмотрим небольшой пример:

Непосредственно перед исполнением функции Main CLR находит все типы, на которые ссылается ее код. В нашем случае метод Main ссылается на единственный тип — Console, и CLR выделяет единственную внутреннюю структуру WriteLine.

Когда Main первый раз обращается к WriteLine, вызывается функция JITCompiler (условное название), которая отвечает за компиляцию IL-кода вызываемого метода в собственные команды процессора. Функции JITCompiler известен вызываемый метод и тип, в котором он определен. JITCompiler ищет в метаданных соответствующей сборки IL-код вызываемого метода, затем проверяет и компилирует IL-код в собственные команды процессора, которые сохраняются в динамически выделенном блоке памяти. После этого JITCompiler возвращается к внутренней структуре данных типа и заменяет адрес вызываемого метода адресом блока памяти, содержащего собственные команды процессора. В завершение JITCompiler передает управление коду в этом блоке памяти. Далее управление возвращается в Main, который продолжает работу в обычном порядке.

Затем Main обращается к WriteLine вторично. К этому моменту код WriteLine уже проверен и скомпилирован, так что производится обращение к блоку памяти, минуя вызов JITCompiler. Отработав, метод WriteLine возвращает управление Main.

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

Промежуточный Язык и JIT компилятор

MSIL – это процессоронезависимый промежуточный язык, созданный Microsoft. MSIL - язык более высокого уровня, чем большинство машинных языков. Он понимает типы объектов и имеет инструкции для создания и инициализации объектов, вызова виртуальных методы и непосредственной манипуляции элементами массива. Он даже имеет инструкции, которые оперируют исключениями. Как и любой другой машинный язык, MSIL может быть написан на ассемблере. Microsoft предоставляет ассемблер и дизассемблер для MSIL.

Перед тем, как выполнять управляемый код CLR должен сначала скомпилировать управляемые MSIL инструкции в инструкции процессора. Здесь возникает типичная проблема: когда пользователь запускает программу, он не намерен ждать пока вся программа скомпилируется, тем более, что большинство функций программы не будут вызваны. Поэтому CLR, компилирует MSIL код в инструкции процессора, когда функции непосредственно вызваны. Всякий раз, когда такая функция вызывается в будущем, сразу выполняется машинный код (а компилятор уже не вовлекается в процесс). Поскольку MSIL компилируется только в нужный момент (just-in-time - JIT), этот компонент CLR часто упоминается как JIT компилятор (JIT compiler) или JITter.

(Перевод: исходный код-> компилятор -> exe/dll (IL и метаданные) –> загрузчик класса -> JIT компилятор с необязательной проверкой -> машинные коды -> выполнение -> проверки безопасности; runtime engine; Библиотеки класов (IL и метаданные); безопасный прекомпилированный код; вызов некомпилированного метода)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]