2014-12-08 7 views
3

Я учусь Java и следующие вещи являются немного запутанным для me.What я понял это:
Разъяснение относительно традиционного интерпретатора, компилятора и JIT-компилятора/интерпретатора (JAVA)

Java от компилятора> Java компилятор просто конвертировать .java-программы в .class файлы, , что означает преобразование исходного кода в байтовый код (это список операционных кодов для виртуальной машины (JVM), который делает Java, независимым от платформы).
Java Interpreter-> просто «интерпретирует» код и НЕ преобразует его в собственный машинный код. Он выполняет каждый инструкции по одному из байт-кода в качестве команды и выполняет его независимо, сколько раз происходит та же команда. (Вот почему это медленно и Java вводит концепцию JIT.)

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

Теперь у меня есть несколько вопросов.

1. Поскольку мой физический процессор понимает только машинный код, как программа Java запускается на выполнение с помощью интерпретатора JVM, как интерпретатор оленьей кожи конвертировать байты-код в машинный code.Untill, и если кто-то не помещает машинный код в память, физический процессор не сможет его выполнить.

2. Предположив, каким-то образом, интерпретатор также преобразует байт-код в машинный код, то «Блок исполнения кода с кэшированием (JIT) и построчного выполнения (интерпретатора)» является единственным, что differenciates JIT и переводчик ?

3. Если во время выполнения выдается JIT преобразует байт-код в машинный код (для выполнения программы) почему не использовать Java раньше времени компиляции, как после создания виртуальной машины Java зависимой байткод (который в свою очередь, делает независимым от Java-плагина), доставляет его на целевую машину (где мы хотим ее выполнить) и просто переводим ее в собственный машинный код (создаем .exe или .out и т. д., как в случае компиляции C). Это может быть возможно, re, имеющих определенную JVM для каждой системы. Это будет намного быстрее, чем использование JIT, поскольку для компиляции/загрузки программы требуется некоторое время, и она по-прежнему будет независимой от платформы, просто распространяя Bytecode (сгенерированный до окончательного перевода с Bytecode на M/c Код).

простите меня, если это глупый вопрос.

ответ

3

Отказ от ответственности: возьмите все это с солью; это довольно упрощенно.

1: Вы правы в том, что сам компьютер не понимает код, поэтому сам JVM необходим. Давайте притворимся, что XY означает «добавить два верхних элемента в стек и нажать результат». JVM затем будет реализован что-то вроде этого:

for(byte bytecode : codeToExecute) { 
    if (bytecode == XX) { 
     // ...do stuff... 
    } else if (bytecode == XY) { 
     int a = pop(); 
     int b = pop(); 
     push(a+b); 
    } else if (bytecode == XZ) { 
     // ...do stuff... 
    } // ... and so on for each possible instruction ... 
} 

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

2: JIT на самом деле не запускает код; все еще выполняется внутри JVM. В принципе, JIT переводит кусок байт-кода в машинный код, когда это необходимо. Когда JVM сталкивается с этим, он думает: «О, эй, это уже машинный код! Сладкий, теперь мне не придется тщательно проверять каждый байт этого, потому что он сам это понимает! прокачайте его, и все будет волшебным образом работать самостоятельно! ».

3: Да, теоретически возможно предварительно скомпилировать код таким образом, чтобы избежать ранних накладных расходов на интерпретацию и JITting. Однако, делая это, вы теряете что-то очень ценное. Вы видите, когда JVM интерпретирует код, он также сохраняет статистику обо всем. Когда он делает JIT код, он знает, как часто используются разные части, позволяя ему оптимизировать его там, где это важно, что делает обычные вещи быстрее за счет редких вещей, что дает общее увеличение производительности.

+0

1.С помощью JVM вы имеете в виду переводчика или комбинацию некоторых других вещей? 2. Вы имеете в виду, что JIt делает задачу интерпретатора намного быстрее, но после JITing требуется интерпретация? 3.Как компилятор JIT может улучшить оптимизацию? Традиционный (B-code to m-code) компилятор может улучшить оптимизацию, так как он имеет полный код, доступный до выполнения. (GCC может сделать очень хорошую оптимизацию в случае C/C++) –

+0

1) JVM в основном означает «то, что запускает Java-программу», которое ВКЛЮЧАЕТ интерпретацию, но также и другие вещи. 2) Да и нет. Даже если класс MyClass был JITted, остальная часть программы все равно может быть интерпретирована. Таким образом, JVM все еще должен быть там, чтобы обрабатывать переходы между интерпретированным и JIT-кодом. 3) Я не знаю никаких примеров из рук в руки. Я точно забыл, какие данные собираются, поэтому мне сложно думать о гипотетическом сценарии. – Smallhacker

+0

Спасибо за вашу помощь. Но мне все же интересно узнать, почему концепция jit была принята, если есть традиционный способ компиляции и оптимизации, который может поддерживать как мобильность, так и хорошую производительность. –

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

  2. Да. Довольно много.

  3. Как вы упомянули, Java рекламировалась как «компилировать один раз, запускать в любом месте». Таким образом, байт-код является важной функцией для выполнения этого обещания. Причина, по которой он не компилируется, когда он поступает на ваш компьютер, является практическим: компиляция выполняется медленно. Обычно это происходит у разработчиков программного обеспечения. Если каждое приложение Java, которое вы запускаете, было скомпилировано в первый раз, вы будете ждать некоторое время.

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

Тем не менее, вы не первый, кто интересно об этом, и на самом деле некоторые люди пишут свои программы в Java, но использовать компилятор на самом деле генерировать исполняемые файлы из них. Компиляторы Java (-to-native) существуют, они просто не являются обычным случаем, потому что многие люди в этот момент используют переносимые C или C++.

+0

1. Ваша первая аналогия прошла над моей головой. 2.если они в значительной степени такие же, а JVM не нуждается в интерпретации после JIT-кода? 3. Хотя традиционная компиляция кода медленная (чем JITing), но один раз, после компиляции, исполняемый файл можно запускать столько раз, сколько мы хотим гораздо быстрее, чем JIT-код каждый раз. Так что с двойной копией и однократной компиляцией будет больше выгодная жертва. –

+0

«Плеер для фортепиано» - это автоматическое фортепиано. Вы видите это в некоторых западных фильмах (вид с ковбоями, обычно не западными). В нем есть тик-лентообразный рулон с отверстиями, который заставляет его играть определенную песню. – uliwitness

+0

@DeepankarSingh Как музыкальная шкатулка. –

Смежные вопросы