2010-01-02 1 views
94

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

Вопрос в том, почему этот скомпилированный код не кэшируется на диск для использования при последующем использовании той же функции/класса?

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

+5

+1 хороший вопрос, что – skaffman

+4

Тема, обсуждающая эту проблему: http://www.javalobby.org/forums/thread.jspa?threadID=15812 – miku

+2

Но маловероятный вопрос для привлечения окончательного ответа. – bmargulies

ответ

25

Не прибегая к cut'n'paste ссылки, которую отправил @MYYN, я подозреваю, что это связано с тем, что оптимизация, которую выполняет JVM, не является статической, а скорее динамической, основанной на шаблонах данных, а также на шаблонах кода. Вероятно, эти шаблоны данных будут меняться в течение срока службы приложения, делая оптимизацию кэширования менее оптимальной.

Таким образом, вам понадобится механизм для определения того, были ли оптимальные оптимизированы сохраненные оптимизации, и в этот момент вы могли бы просто повторно оптимизировать «на лету».

+4

... или вы можете просто настойчиво продолжать использовать * вариант *, например, JVM от Oracle - расширить возможности продвинутых программистов *, чтобы оптимизировать производительность своих приложений, когда и где они просто ** знают **, шаблоны ** не ** изменяясь под их ответственностью. Почему нет?! –

+2

Потому что это, вероятно, не стоит. Если ни SUN, ни IBM, ни BEA не считают это стоящим для их JVM производительности, это будет хорошей причиной для этого. Возможно, их оптимизация RT быстрее, чем Oracle, поэтому Oracle кэширует ее. – skaffman

+8

Почему бы не взять сохраненные оптимальные значения в качестве отправной точки, чтобы использовать то, что было изучено в предыдущих запусках? Оттуда JIT может работать как обычно, переустанавливать материал. При выключении этот код может быть сохранен снова и использоваться в следующем запуске в качестве новой отправной точки. – Puce

24

Oracle's JVM действительно документален сделать это - цитирует Oracle,

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

Я не знаю, почему все сложные версии VM не предлагают аналогичные варианты.

+7

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

+0

Вау! это означает, что компиляции кэшируются время от времени. Это хорошие новости! –

+0

IBM J9 также документирован для этого. – user314104

1

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

  • Идея Java должна быть вписанный оновлено язык с произвольным доступом и размещение прекомпилированных материалов в файле класса является своего рода нарушением (только «вид», потому что, конечно, фактический байт-код все равно будет там)
  • Это увеличило бы размеры файлов классов, потому что у вас было бы один и тот же код несколько раз, особенно если вы запускаете ту же программу в нескольких разных JVM (что не очень редко, когда вы рассматриваете разные версии как разные JV Ms, что вам действительно нужно делать)
  • Файлы классов могут быть недоступны для записи (хотя это было бы довольно легко проверить)
  • Оптимизации JVM частично основаны на информации о времени выполнения и на других запусках они могут быть не такими применимыми (хотя они все равно должны принести некоторую выгоду)

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

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

+1

есть место в файле classfile для таких вещей, infact, который был первоначальным намерением (хранить JIT-код в качестве атрибута в файле класса). – TofuBeer

+0

@TofuBeer: Спасибо за подтверждение. Я подозревал, что это может быть так (это то, что я бы сделал), но не был уверен. Отредактировано, чтобы удалить это как возможную причину. – JaakkoK

+0

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

5

Excelsior JET имеет кэширование JIT компилятор начиная с версии 2.0, который был выпущен еще в 2001 году Кроме того, его АОТ компилятор может скомпилировать кэш в единый DLL/общий объект, используя все оптимизации.

+3

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

10

Обновленный к существующим ответам - Java 8 имеет JEP посвященного решению этого:

=>JEP 145: Cache Compiled Code. New link.

На очень высоком уровне, его заявленная целью является:

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

Надеюсь, это поможет.

+3

Функция не дошла до [окончательной версии] (http://openjdk.java.net/projects/jdk8/features). – assylias

+2

Неработающая ссылка. --- –

+1

См. Также (http://stackoverflow.com/questions/39394819) – MRalwasser

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