Компиляция кода .NET или усложнение?


Q1) почему C# изначально компилируется в IL, а затем во время выполнения JIT выполняется и выполняется поверх виртуальной машины(?). Или это JIT соответствует нативному машинному коду?

Q2) если второе верно (JIT соответствует машинному коду), то где находится .NET sandbox, в котором выполняется код?

Q3) кроме того, почему код компилируется в IL в первую очередь. Почему бы просто не компилировать в машинный код все время? Есть инструмент от MS от этого называется ngen но почему это так необязательно?

6 7

6 ответов:

IL-это JIT'D (JIT = Just In Time), скомпилированный в машинный код по мере выполнения процесса.

Использование уровня виртуальных машин позволяет .NET вести себя согласованно на разных платформах (например, int всегда имеет 32 бита независимо от того, работаете ли вы на 32 - или 64 - разрядной машине, это не относится к C++).

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

A1) JIT компилируется в машинный код

A2)в .net нет такого термина, как песочница. Вместо этого есть Домены приложений. И они выполняются как часть CLR (то есть как часть исполняемого процесса)

A3) недостатки NGen от Джеффри Рихтера:

  • Файлы Ngen'D могут выйти из синхронизации. Когда CLR загружает файл Ngen'D, он сравнивает количество характеристик о ранее скомпилированном коде и текущем выполнении окружающая среда. Если какие-либо характеристики не совпадают, файл Ngen'D не может быть используется, и вместо этого используется обычный процесс компилятора JIT.

  • Низкая Производительность При Нагрузке (Ребазинг / Привязка). Файлы сборок являются стандартными файлами Windows PE, и поэтому каждый из них содержит предпочтительный базовый адрес. много окон разработчики знакомы с проблемами, связанными с базовыми адресами и ребазингом. При компиляции кода JIT эти проблемы не являются проблемой, так как при выполнении вычисляются правильные ссылки на адреса памяти время.

  • Низкая Производительность По Времени Выполнения. При компиляции кода NGen не может сделать столько же предположения о среде выполнения, как JIT-компилятор может. Эта причина Ngen платформы.exe, чтобы произвести неполноценный код. Например, NGen не оптимизирует использование определенные инструкции ЦП; он добавляет косвенные ссылки для статического доступа к полю, поскольку фактический адрес статических полей известен только во время выполнения. NGen вставляет код для вызова класса конструкторы везде, потому что он не знает порядок, в котором будет выполняться код и если конструктор класса уже был вызван.

Вы можете использовать ngen платформы для создания собственных версий .Net-сборок. Это означает, что JIT не должен делать этого во время выполнения.

.NET компилируется сначала в IL, а затем в native, поскольку JIT был разработан для оптимизации кода IL для текущего процессора, под которым выполняется код.

.NET-код компилируется в IL для совместимости. Поскольку вы можете создавать код с помощью C#, VB.NET, и т. д. Тогда JIT нужен общий набор команд (IL) для компиляции в машинный код. Если JIT должен быть осведомлен о языках,а затем JIT должен быть обновлен, когда будет выпущен новый язык .NET.

Я не уверен в вопросе песочницы, мое лучшее предположение заключается в том, что приложение .NET работает с 3 доменами приложений. Один домен содержит .NET runtimes (mscorlib, system.dll и т. д.), другой домен содержит ваш .NET-код, и я не могу вспомнить, для чего предназначен другой домен. Проверить http://my.safaribooksonline.com/9780321584090

1. C# компилируется в CIL (или IL), поскольку он имеет общую платформу с остальными языками .NET (именно поэтому вы можете написать DLL в C# и использовать ее в VB.NET или F# без хлопот). CLR Затем JIT скомпилирует код в машинный код.

.NET также можно запускать на нескольких платформах (Mono на *NIX и OS X). Если бы C# компилировался в машинный код, это было бы не так просто.

2. нет никакой песочницы.

3. покрыто в ответе на #1

A1) таким образом, это платформа agnostic (Windows, Linux, Mac), и она также может использовать определенные оптимизации для вашего текущего оборудования. Когда он получает JIT-компиляцию, это машинный код.

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

A3) как и в ответе 1, он позволяет двоичному файлу .NET работать на разных платформах и выполнять определенные оптимизации в клиентской машине на летать.

Скомпилированный .Net-код становится IL, который является промежуточным языком точно так же, как и объектный код Javas. Да, можно сгенерировать машинный код с помощью инструмента NGen. Ngen связывает полученный собственный образ с машиной, поэтому копирование двоичного файла ngen'D в другую систему не приведет к ожидаемым результатам. Компиляция в промежуточный код позволяет принимать решения во время выполнения, которые в противном случае (легко) не могут быть приняты с помощью статически типизированного языка, например C++, он также позволяет функционировать коду на различных аппаратных архетектурах, потому что код тогда становится описательным в том смысле, что он также описывает намерение того, что должно произойти в битном (например, 32 или 64)-агностическом способе, в отличие от машинного кода, который работает только на 32-битных системах или 64-битных системах, но не на обоих.

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