#java #jvm
Что делает jvm? Учитывая все особенности среды в которой она работает (так как она именно под нее написана), интерпретирует байт-код, то есть динамически превращает в машинный код. Так вот, почему нельзя единожды, при "установке" программы (то есть первом попадании) на компьютер с помощью jvm скомпилировать байт-код в машинный код и дальше уже не использовать jvm? Ускорение ведь будет серьезное и может чуток памяти высвободится за счет отсутствия jvm. Ведь есть же JIT который делает то же самое, но во время выполнения программы и лишь кусками.
Ответы
Ответ 1
Так вот, почему нельзя единожды, при "установке" программы (то есть первом попадании) на компьютер с помощью jvm скомпилировать байт-код в машинный код и дальше уже не использовать jvm? Потому что тогда нельзя будет использовать спекуляции, за счет которых JIT-скомпилированный код вполне легально может обгонять AOT-скомпилированный код. Например, у нас может быть метод со следующей сигнатурой: void push(Consumerconsumer) В этом случае АОТ ничего не останется кроме того, чтобы использовать интерфейс Consumer и вычислять реально вызываемый метод в рантайме. Однако если JIT на момент компиляции видит, что метод был вызван пять тысяч раз с одной и той же имплементацией Consumer - он может отбросить все лишнее, вызывать напрямую заранее известный метод и поставить перед этим т.н. trap на случай, если в метод все-таки упадет другая имплементация, и его надо будет перекомпилировать. Также JIT позволяет эффективный инлайнинг кода, который также происходит на основе учета количества вызовов и размера метода. АОТ не может знать, какой участок будет горячим без помощи программиста (который, в свою очередь, может ошибаться), а JIT - вполне. Ведь есть же JIT который делает то же самое, но во время выполнения программы и лишь кусками. JIT не делает этого кусками, весь код рано или поздно будет скомпилирован в машинный, просто пока компилятор не отработал, работает интерпретатор. Благодаря этому мы и можем, например, получить ассемблерный листинг. Ответ 2
Небольшое не очень профессиональное объяснение работы исполнителей языка. Существуют: Компиляторы. Интерпретаторы. И компилятора интерпретаторы, или интерпретаторы компилирующего Типа. Отбросим первые два, и обсудим третий. Компилятор интепретирующего типа, это по сути компилятор и интерпретатор два в одном, поимер такого исполнителя это JVM, после написания текста программы, JVM в первую очередь использует компилятор, который компилирует ваш текст в байт-код, при этом этот этап имеет ряд оптимизаций, например пустые циклы, не проходят в байт-код, также бывает такое, что компилятор транслирует текст вообще в чистый машинный код, благодаря этому, достигается такая сумасшедшая скорость. Но следующим этапом, будет исполнения этого байт-кода, и вот этим, уже занимается JIT интерпретатор, которые интерпретирует машинный и байт коды, выводя нам результат. Соответственно теперь вы сами должны понять, почему нельзя добиться единоразового исполнения — программа на половину, исполняется динамически, то есть, если байт код мы в принципе можем единожды скомпилировать, но интерпретировать байт-код нужно каждый раз уникально. Такая технология называется JIT интерпретаторы. И-то все что я здесь описал, это без учета многих других моментов, оптимизаций, хаков и технологий... Но насколько мне известно, из любого приложения на Java Например, можно добиться итогового исполняемого файла, другой вопрос будет ли удобно каждый раз добиваться исполняемого файла и зачем вам тогда вообще язык на JVM? Ведь плюсы таких языков объективно видны на серверах, например.Ответ 3
Для классов стандартной библиотеки это уже делается начиная с Java 9. Есть мнение, что после всесторонней обкатки AOT-компилятор станет доступен и для пользовательских классов.Ответ 4
почему нельзя единожды, при "установке" программы (то есть первом попадании) на компьютер с помощью jvm скомпилировать байт-код в машинный код и дальше уже не использовать jvm? Ответ очень простой, jvm - это программа которая уже скомпилирована в машинный код. jvm не может компилировать код вашей программы в машинный код при "установке" программы, так как не являтся компилятором. В составе JDK имеется компилятор с языка Java, который компилирует в байткод. Байткод не является машинным кодом, поэтому может выполняться только на jvm. Хотя, в природе были известны компиляторы с языка Java, такие как gcj, но они почему-то не очень популярны. Вот еще одна имплементация AOT, так называемая GraalVM. Представялет из себя подмену JVM другой виртуальной машиной. Компиляция AOT: Полученная программа не запускается на виртуальной машине Java HotSpot, но использует необходимые компоненты, такие как управление памятью, планирование потоков из другой реализации виртуальной машины под названием «Субстратная виртуальная машина». Субстрат VM написан на Java и скомпилирован в собственный исполняемый файл.
Комментариев нет:
Отправить комментарий