Что делает just-in-time (JIT) компилятор?


Что конкретно делает JIT-компилятор в отличие от не-JIT-компилятора? Может ли кто-нибудь дать краткое и понятное описание?

18 439

18 ответов:

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

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

перефразируя, обычные компиляторы строят всю программу как EXE-файл перед ее первым запуском. Для более новых программ стиля сборка создается с псевдокодом (p-кодом). Только после того, как вы выполните программу на ОС (например, дважды щелкнув по ее значку), компилятор (JIT) включится и сгенерирует машинный код (m-код), который Процессор на базе Intel или что-то еще поймет.

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

в какой-то момент эволюции языков компиляторы скомпилируют язык высокого уровня в псевдокод, который затем будет интерпретирован (интерпретатором) для запуска вашей программы. Это устранило объектный код и исполняемые файлы и позволило им языки должны быть переносимыми на несколько операционных систем и аппаратных платформ. Паскаль (который скомпилирован в P-код) был одним из первых; Java и C# являются более поздними примерами. В конце концов термин P-код был заменен байт-кодом, так как большинство псевдо-операций имеют длину байта.

JIT-компилятор-это функция интерпретатора времени выполнения, которая вместо интерпретации байт-кода при каждом вызове метода будет компилировать байт-код в машинный код инструкции запущенной машины, а затем вызвать этот объектный код вместо этого. В идеале эффективность выполнения объектного кода позволит преодолеть неэффективность перекомпиляции программы при каждом ее запуске.

JIT - как раз вовремя само слово говорит, когда это необходимо (по требованию)

типичный сценарий:

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

JIT сценарий:

исходный код будет преобразован в ассемблер как структура [для ex IL (промежуточный язык) для C#, байт-код для java].

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

JIT vs non-JIT сравнение:

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

  • как машинный код будет сгенерирован во время выполнения....в JIT компилятор будет создание машинного кода, оптимизированного для работы архитектура процессора машины.

JIT примеры:

  1. в Java JIT находится в JVM (виртуальная машина Java)
  2. в C# он находится в среде CLR (Common Language Runtime)
  3. в Android он находится в DVM (Dalvik Virtual Machine) или ART (Android RunTime) в более новых версиях.

как другие упомянули

JIT означает Just-In-Time, что означает, что код компилируется, когда это необходимо, а не до выполнения.

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

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

JIT означает Just-In-Time, что означает, что код компилируется, когда это необходимо, а не до выполнения.

Это полезно, потому что компилятор может генерировать код, оптимизированный для вашей конкретной машины. Статический компилятор, как и ваш средний компилятор C, будет компилировать весь код в исполняемый код на машине разработчика. Следовательно, компилятор будет выполнять оптимизацию, основанную на некоторых предположениях. Он может компилироваться медленнее и делать больше оптимизаций, потому что это не замедляет выполнение программы пользователя.

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

когда нам нужно вызвать метод несколько раз, мы должны интерпретировать один и тот же код много раз и это может занять больше времени, чем необходимо. Итак, у нас есть JIT (just-in-time) компиляторы. Когда байт был загружен в JVM (его время выполнения), весь код будет скомпилирован, а не интерпретирован, что позволит сэкономить время.

JIT-компиляторы работают только во время выполнения, поэтому у нас нет двоичного вывода.

JIT-компилятор компилирует только байт-код в эквивалентный машинный код при первом выполнении. При каждом последующем выполнении JVM просто использует уже скомпилированный собственный код для оптимизации производительности.

enter image description here

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

enter image description here

источник

как раз вовремя компилятор (JIT):
Он компилирует байт-коды java в машинные инструкции этого конкретного процессора.

например, если у нас есть оператор цикла в нашем коде java:

while(i<10){
    // ...
    a=a+i;
    // ...
 }

приведенный выше код цикла выполняется 10 раз, если значение i равно 0.

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

другим подобным примером является поиск шаблона с использованием "регулярного выражения" в списке строк/предложений.

JIT-компилятор не компилирует код в машинный код. Он компилирует код, который имеет аналогичная картина во время выполнения.

посмотреть этот документация Oracle по пониманию JIT читать больше.

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

Я знаю, что это старый поток, но оптимизация времени выполнения-еще одна важная часть компиляции JIT, которая, похоже, не обсуждается здесь. В принципе, JIT-компилятор может контролировать программу по мере ее запуска, чтобы определить способы улучшения выполнения. Затем он может внести эти изменения "на лету" во время выполнения. Оптимизация Google JIT (javaworld имеет довольно хорошая статья об этом.)

Jit расшифровывается как раз вовремя компилятор jit-это программа, которая превращает байтовый код java в инструкцию, которая может быть отправлена непосредственно процессору.

использование компилятора java just in time (действительно второго компилятора) на конкретной системной платформе соответствует байт-коду в конкретный системный код,как только код был повторно скомпилирован JIT-компилятором ,он обычно будет работать быстрее на компьютере.

компилятор just-in-time поставляется с виртуальным машина и использована выборочно. Он компилирует байт-код в специфичный для платформы исполняемый код, который немедленно выполняется.

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

в следующих примерах кода показано, как JIT оптимизирует код Java.

Код Перед Оптимизацией

    class A {
      B b;
      public void newMethod() {
        y = b.get();
        ...do stuff...
        z = b.get();
        sum = y + z;
      }
    }

class B {
   int value;
   final int get() {
      return value;
   }
}

Код После Оптимизации

class A {
B b;
public void newMethod() {
   y = b.value;
   ...do stuff...
   sum = y + y;
}
}
class B {
   int value;
   final int get() {
      return value;
   }
}

первоначально код содержал два вызова метода b. get (). После оптимизации два вызова метода оптимизируются в одну операцию копирования переменной; то есть оптимизированному коду не нужно выполнять вызов метода, чтобы получить значение поля класса B.

just-in-time (JIT) компиляция, (также динамический перевод или компиляция во время выполнения), является способ выполнения машинный код это включает компиляцию во время выполнения программы – во время выполнения – , а не до исполнения.

это компиляция сочетание два традиционных подхода к переводу в машинный код – опережающая компиляция (AOT) и толкование – и сочетает в себе некоторые преимущества и недостатки обоих. JIT-компиляция сочетает в себе скорость скомпилированного кода с гибкостью толкования.

давайте рассмотрим JIT, используемый в JVM,

например, компиляторы JIT HotSpot JVM генерируют динамические оптимизации. Другими словами,они принимают решения по оптимизации во время работы приложения Java и генерируют высокопроизводительные собственные машинные инструкции предназначенные для базового системная архитектура.

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

дерево трассировки-это структура данных, которая используется при компиляции программного кода во время выполнения. Деревья трассировки используются в типе "just in time compiler", который отслеживает код, выполняемый во время горячих точек, и компилирует его. См.этой.

см. :

20% байтового кода используется 80% времени. JIT-компилятор получает эти статистические данные и оптимизирует эти 20% байтового кода, чтобы работать быстрее, добавляя встроенные методы, удаление неиспользуемых блокировок и т. д., а также создавая байт-код, специфичный для этой машины. Я цитирую из этой статьи, я нашел, что это было удобно. http://java.dzone.com/articles/just-time-compiler-jit-hotspot

JIT относится к движку выполнения в нескольких реализациях JVM, который быстрее,но требует больше памяти, является компилятором just-in-time. В этой схеме байт-коды метода компилируются в собственный машинный код при первом вызове метода. Затем собственный машинный код для метода кэшируется, поэтому его можно повторно использовать при следующем вызове того же метода.

JVM фактически выполняет шаги компиляции во время выполнения по причинам производительности. Это означает, что Java не имеет чистого разделения компиляции и выполнения. Сначала он выполняет так называемую статическую компиляцию из исходного кода Java в байт-код. Затем этот байт-код передается в JVM для выполнения. Но выполнение байт-кода происходит медленно, поэтому JVM измеряет, как часто выполняется байт-код, и когда он обнаруживает "горячую точку" кода, который выполняется очень часто, он выполняет динамическую компиляцию из байт-кода в машинный код кода "hotspot" (hotspot profiler). Так эффективно сегодня Java-программы выполняются с помощью выполнения машинного кода.

just in time compiler (JIT) - это часть программного обеспечения, которая принимает не исполняемый вход и возвращает соответствующий машинный код для выполнения. Например:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

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

разница компилятор, интерпретатор и JIT

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

  1. компилятор: принимает исходный код и возвращает исполняемый файл
  2. переводчик: выполняет инструкцию программы по инструкции. Он берет исполняемый сегмент исходного кода и превращает этот сегмент в машинные инструкции. Этот процесс повторяется до тех пор, пока весь исходный код не будет преобразован в машинные инструкции и выполнен.
  3. JIT: много различных реализаций JIT являются возможно, однако JIT обычно представляет собой комбинацию комплимента и интерпретатора. JIT сначала превращает промежуточные данные (например, байт-код Java), которые он получает на машинный язык через интерпретацию. JIT часто может чувствовать, когда определенная часть кода выполняется часто, и будет компилировать эту часть для более быстрого выполнения.