2014-10-21 4 views
2

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

Однако я не мог найти такие файлы в папках проекта. Существуют только папки bin и src, которые содержат * .class байт-коды и * .java исходные коды.

Так что мои вопросы:

  1. Если Java интерпретирует байт-кода все время, почему бы не перевести байткод в машинный код после первого запуска?

  2. Если они действительно генерируют машинный код, где находятся файлы?

+1

Зачем тратить время на компиляцию кода, который, возможно, никогда не будет запущен в течение жизни JVM? – BarrySW19

ответ

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

Если Java интерпретирует байт-код все время, почему бы не перевести байт-код в машинный код после первого запуска?

Есть доводы за и против как досрочно (AOT), так и как раз вовремя (JIT).

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

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

Некоторые языки предназначены для одного подхода к другому. Например, C/C++ предназначены для AOT, тогда как Java предназначен для JIT (хотя он может быть скомпилирован AOT с некоторыми ограничениями). Например, Java уделяет большое внимание виртуальным геттерам и сеттерам, возможно, для классов, не загруженных до времени исполнения. Но JIT может видеть и встроить эти функции во время выполнения. В отличие от этого, если вы использовали виртуальные методы для каждого доступа к полю в C++, вы заплатили бы огромную штрафную производительность.

0
  1. Он не интерпретирует код все время. Интерпретированный код через некоторое время переводится в байтовый код. Вы можете настроить это «время» с помощью -XX: CompileThreshold = (по умолчанию - 10000), или вы можете полностью отключить компиляцию.

  2. В памяти. В памяти есть специальная область под названием «Кодовый кеш». Вы можете увидеть, как методы скомпилированы в кеш и как они выведены из кеша, используя -XX: + PrintCompilation. Размер кеша также настраивается, см. -XX: ReservedCodeCacheSize =.

0

Ну, JVM имеет предварительно обработанные данные, но только для своих классов.Учитывая размер библиотеки JRE и тот факт, что она обычно не меняется, это большая победа (вы можете искать файлы под названием classes.jsa).

Однако даже эти файлы не содержат собственный код, а только более простой в обработке байтовый код.

Большая точка генерации кода в JVM Hot Spot заключается в том, что они не компилируют код на основе класса или метода, как вы, кажется, думаете. Эти JVM компилируют фрагменты кода, охватывающие несколько взаимодействующих методов, поскольку взаимодействие обнаруживается во время самопрофилирования. Эти кодовые блоки могут охватывать методы из JRE, библиотек расширений, сторонних библиотек в вашем пути к классу и ваших классов приложений и, следовательно, действительны только для этой конкретной комбинации.

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

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