2015-08-20 1 views
1

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

Компилятор C++ только переводит код в машинный язык или собственный код. Этот собственный код выполняется процессором.

Из того, что я читал в сети, Java-программа изначально компилируется в Bytecode с помощью java-компилятора javac. Этот байт-код затем интерпретируется (и выполняется) по линейной основе виртуальной машиной Java.

У меня есть несколько запросов.

1) Если C++ не является независимой от платформы, поскольку разные компиляторы должны быть сконструированы для разных архитектур процессора, то не отличается ли JVM от одного оборудования к другому?

2) Если я написал код на C++ и скомпилировал и выполнил его на машинах 1 и 2, результат будет таким же. Точно так же, если я пишу программу Java и выполняю ее на двух разных машинах, вывод будет все тот же. Почему дополнительный шаг генерации байткода?

3) Я где-то читал, что переводчики, в отличие от компиляторов, фактически выполняют программу путем эмуляции виртуальной машины. Означает ли это, что JVM фактически выполняет байт-код, а не просто интерпретирует его в собственный код?

+1

Прочитайте http://stackoverflow.com/q/2748910/1110928 и http://stackoverflow.com/q/2203248/1110928. Я утверждаю, что это дубликат второго вопроса, который я перечислил. Короче говоря, вы могли бы думать о JVM как эмулированном процессоре, поэтому набор команд байткода одинаковый для любого оборудования. – apnorton

+0

Я все еще не понимаю, почему исходный код напрямую не интерпретируется и не выполняется JVM. –

+0

Итак, вы спрашиваете: «Почему мы компилируем байт-код как промежуточный, вместо того, чтобы делать то, что, скажем, Python, путем компиляции и интерпретации« на лету »? – apnorton

ответ

2

В некотором смысле вы правы, поскольку вы можете по существу сопоставить компилятор C++ с комбинацией Java-компилятора и виртуальной машины Java. Ни один из этих двух сам по себе не является независимым от платформы: компилятор Java, написанный для Linux-машины, обычно не запускается на компьютере под управлением Windows, и ни одна из них не будет JVM.

Однако на практике промежуточный язык байт-кода Java, который производит компилятор Java и выполняется виртуальной машиной, имеет огромное значение, поскольку на этом уровне отправляется скомпилированный код. Поэтому, если вы получаете двоичный код Java, это байт-код. Если у вас есть JVM для вашего устройства, вы можете запустить его без лишних хлопот. Напротив, двоичный код C++ представляет собой машинный код для конкретной машины; вы не можете запустить его на другой машине, кроме той, для которой она была скомпилирована.

Теперь, чтобы прийти к вашим актуальным вопросам:

  1. Действительно, JV отличаются от одной аппаратной платформы на другую.
  2. Шаг компиляции к байт-коду позаботится об обработке и упаковке. Если вы захотите сделать это каждый раз, когда запускаете программу, время запуска будет страдать. Но это, безусловно, возможно в принципе, так что да, если вы напишите обертку вокруг компилятора C++, который вызывает компилятор, а затем сразу же выполняет скомпилированную программу, у вас фактически есть виртуальная машина для C++, которая так же независима от платформы, как и выполнение Java байт-код.
  3. Современные JVM очень умны и выполняют некоторую дополнительную компиляцию во время исполнения байт-кода (называемый Just-In-Time или JIT-компиляция). Это вовсе не просто интерпретация байт-кода.
2

C++ с однократной записью, компилировать в любом месте (по крайней мере в теории, легче сказать, чем сделать, но это делается)

Ява компилировать один раз, работает в любом месте (при условии, JVM установлен, опять различия между системами, которые не могут быть скрыты полностью)

Если C++ не зависит от платформы, потому что разные компиляторы должны быть разработаны для различных архитектур процессоров, то не JVM отличается от одного аппаратных к другому, а?

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

Если я написал код на C++ и скомпилировал и выполнил его на машинах 1 и 2, результат будет таким же. Точно так же, если я пишу программу Java и выполняю ее на двух разных машинах, вывод будет все тот же. Почему дополнительный шаг генерации байткода?

Вам нужно всего лишь скомпилировать его один раз для Java. Вы можете взять JAR, скомпилированный с использованием Java 1.0 на 32-битной платформе Windows под управлением Windows 95 двадцать лет назад, и немедленно использовать ее без источника или знать, как она скомпилирована, на 64-разрядном процессоре ARM под управлением Linux, и он будет использовать последние оптимизация и набор инструкций для этого процессора.

Для C++, если вы используете программу, написанную на Windows 95 двадцать лет назад, она, вероятно, не будет компилировать без много работы и тестирования на 64-битном процессоре ARM для Linux.

Я где-то читал, что переводчики, в отличие от компиляторов, фактически выполняют программу путем эмуляции виртуальной машины. Означает ли это, что JVM фактически выполняет байт-код, а не просто интерпретирует его в собственный код?

Виртуальная машина Java интерпретирует изначально, компилирует его быстро, а затем медленнее (Вызывается С1 в OpenJDK) и позже повторно otimises более агрессивно (так называемый С2) Он проходит через 4-х различных уровней компиляции и он может отменить оптимизации кода чтобы он был повторно оптимизирован на основе изменения использования и даже изменения кода.

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