Подтвердить что ты не робот

CLR против JIT

В чем разница между JIT-компилятором и CLR? Если вы скомпилируете свой код, чтобы il и CLR запускали этот код, то что делает JIT? Как скомпилирована JIT-компиляция с добавлением генериков в CLR?

4b9b3361

Ответ 1

JIT - это один из аспектов CLR.

В частности, это часть, ответственная за изменение CIL/MSIL (далее IL), созданного компилятором исходного языка (например, csc.exe для Microsoft С#), в машинный код, свойственный текущему процессору (и архитектуре, которую он предоставляет в текущий процесс, например 32/64 бит). Если рассматриваемая сборка была ngen'd, тогда процесс JIT совершенно не нужен, и CLR будет работать с этим кодом просто отлично без него.

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

Чтобы обратиться к добавлению Generics.

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

Было добавлено несколько новых инструкций по IL, и для типов инструментов и членов было предоставлено больше опций метаданных. На уровне IL были добавлены ограничения.

Когда JIT компилирует метод, который имеет общие аргументы (явно или неявно через содержащийся класс), он может настраивать разные коды кода (инструкции машинного кода) для каждого используемого типа. На практике JIT использует общую реализацию для всех ссылочных типов, поскольку переменные для них будут иметь одну и ту же семантику и занимать одно и то же пространство (IntPtr.Size).

Каждый тип значения получит конкретный код, сгенерированный для него, поскольку причиной уменьшения/увеличения размера переменных в стеке/куче является серьезная причина. Кроме того, вызывая ограниченный код операции перед вызовом метода, многие вызовы в не ссылочных типах не должны включать значение для вызова метода (эта оптимизация используется также в не общих случаях). Это также позволяет корректно обрабатывать поведение по умолчанию <T> и сравнивать с нулем, которое должно быть удалено, поскольку никакие ops (всегда false), когда используется тип значения Nullable.

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

Ответ 2

Вы компилируете свой код в IL, который запускается и компилируется в машинный код во время выполнения, это называется JIT.

Изменить, чтобы отформатировать ответ еще (все еще слишком упрощен):

Когда вы компилируете свой С# -код в visual studio, он превращается в IL, который CLR понимает, IL является одинаковым для всех языков, работающих поверх CLR (что позволяет среде выполнения .NET использовать несколько языков и между ними легко).

Во время выполнения IL интерпретируется в машинный код (который специфичен для архитектуры, в которой вы находитесь), а затем выполняется. Этот процесс называется Just In Time компиляции или JIT для краткости. Только необходимый IL преобразуется в машинный код (и только один раз он "кэшируется" после компиляции в машинный код), как раз вовремя, прежде чем он будет выполнен, поэтому имя JIT.

Это то, что было бы похоже на С#

С# Code > Компилятор С# > IL >.NET Runtime > JIT-компилятор > Machinecode > Выполнение

И это то, что было бы похоже на VB

VB Code > Компилятор VB > IL >.NET Runtime > JIT-компилятор > Machinecode > Выполнение

И как вы можете видеть, только два первых шага уникальны для каждого языка, и все после того, как оно было превращено в IL, является тем же самым, что, как я уже говорил, является причиной того, что вы можете запускать несколько разных языков. NET

Ответ 3

Как говорит Джон Скит, JIT является частью CLR. В основном это то, что происходит под капотом:

  • Исходный код скомпилирован в байтовый код, известный как общий промежуточный язык (CIL).
  • Метаданные из каждого класса и всех методов (и все остальное: O) включаются в PE-заголовок результирующего исполняемого файла (будь то dll или exe).
  • Если вы создаете исполняемый файл, заголовок PE также включает обычный загрузочный носитель, который отвечает за загрузку CLR (Common language runtime) при выполнении исполняемого файла.

Теперь, когда вы выполните:

  • Бутстрастер инициализирует CLR (главным образом, загружая сборку mscorlib) и инструктирует ее выполнить вашу сборку.
  • CLR выполняет основную запись.
  • Теперь классы имеют векторную таблицу, в которой хранятся адреса функций метода, поэтому при вызове MyMethod эта таблица выполняется, а затем выполняется соответствующий вызов по адресу. После запуска ВСЕ записи для всех таблиц имеют адрес компилятора JIT.
  • Когда вызов одного из таких методов выполняется, JIT вызывается вместо фактического метода и берет управление. JIT затем компилирует код CIL в фактический код сборки для подходящей архитектуры.
  • После компиляции кода JIT переходит в таблицу векторов метода и заменяет адрес на один из скомпилированного кода, так что каждый последующий вызов больше не вызывает JIT.
  • Наконец, JIT обрабатывает выполнение скомпилированного кода.
  • Если вы вызываете другой метод, который еще не скомпилирован, вернитесь к 4... и так далее...

Ответ 4

JIT является в основном частью CLR. Сборщик мусора - другой. Совсем, где вы ставите обязанности interop и т.д., Это другое дело, и я очень недооценил комментарий:)

Ответ 5

Я знаю, что нить довольно старая, но я подумал, что смогу нарисовать картинку, которая заставила меня понять JIT. Это отличная книга CLR через С# Джефри Ричер. На изображении метаданные, о которых он говорит, - это метаданные, испускаемые в заголовке сборки, где хранится вся информация о типах в сборке:

JIT image from CLR via C#

Ответ 6

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

2) при выполнении программы код промежуточного языка преобразуется в операционную систему. Исходный код как и когда вызывается метод; это называется компиляцией JIT (Just in Time).

Ответ 7

  • Common Language Runtime (CLR) - это интерпретатор, а Just In Time (JIT) - это компилятор в .Net Framework.

2.JIT является внутренним компилятором .NET, который берет код CLI промежуточного кода Microsoft (MSICL) из CLR и выполняет его для машинных конкретных инструкций, тогда как CLR работает как двигатель, его основной задачей является предоставление кода MSICL для JIT для обеспечения этот код полностью компилируется в соответствии со спецификацией машины.