Почему интерпретация java-байт-кода?

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

Ответы

Ответ 1

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

В книге Создатели для программирования, Джеймс Гослинг пояснил:

Джеймс: Точно. В эти дни избивая действительно хорошие C и С++ компиляторы почти всегда. Когда ты перейдите в динамический компилятор, вы получите два преимущества, когда компиляторы бегущая прямо в последний момент. Один вы точно знаете, какой набор микросхем вы бежите дальше. Так много раз, когда люди компилируют кусок C кода, они должны скомпилировать его для запуска по виду общего x86 архитектура. Почти ни одна из бинарные файлы, которые вы получаете, особенно хороши настроенный для любого из них. Вы загружаете последняя копия Mozilla, и itll работает практически во всех Intel архитектура CPU. В значительной степени один Linux файл. Его довольно общий, и его скомпилированный с помощью GCC, который не очень хороший компилятор C.

Когда HotSpot работает, он точно знает какой чипсет вы работаете. Это точно знает, как работает кеш. Это точно знает, как иерархия памяти работает. Он точно знает, как все межблочные блокировки работают в ЦП. Он знает, какой набор инструкций расширения этого чипа. Это оптимизирует для какой именно машины Вы на. Тогда другая половина заключается в том, что он фактически видит приложения в качестве его запуска. Его способность иметь статистику, которая все важно. Его способность встроенные вещи, которые компилятор C мог никогда не делай. То, что получает встроенный в мир Java довольно удивительно. Затем вы как управление хранилищем работает с современные сборщики мусора. С современный сборщик мусора, хранилище распределение происходит очень быстро.

Ответ 2

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

Ответ 3

Интерпретация байткода обычно достаточно "достаточно быстрая" для многих случаев. Компиляция, с другой стороны, довольно дорога. Если 90% времени выполнения тратится на 1% от кода, гораздо лучше всего составить 1% и оставить остальные 99%.

Ответ 4

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

Ответ 5

Одним из важных различий в динамическом компиляции является то, что он оптимизирует базу кода до тех пор, пока она не запущена. Существует опция -XX:CompileThreshold=, которая по умолчанию равна 10000. Вы можете уменьшить это, чтобы он быстрее оптимизировал код, но если вы запускаете сложное приложение или тест, вы можете обнаружить, что сокращение этого числа может привести к более медленному коду. Если вы запускаете простой тест, вы можете не обнаружить, что это имеет значение.

Один пример, когда динамическая компиляция имеет преимущество перед статическим компиляцией, - это вложение "виртуальных" методов, особенно тех, которые могут быть заменены. Например, JVM может встроить до двух сильно используемых "виртуальных" методов, которые могут быть в отдельном банке, скомпилированном после компиляции вызывающего. Вызываемые банки могут быть даже удалены из бегущей системы, например. OSGi и добавить еще одну банку или заменить ее. Затем могут быть добавлены методы замены JAR. Это может быть достигнуто только при динамическом компиляции.

Ответ 6

Java Bytecode интерпретируется, потому что байт-коды переносимы на разных платформах. JVM, который зависит от платформы, преобразует и исполняет байт-коды в определенный набор команд этого компьютера независимо от того, может ли он быть Windows или LINUX или MAC и т.д.