В Java 9 появится Ahead-Of-Time компиляция. Это как? — новости на Tproger
Недавно стало окончательно известно — в Java 9 будет AOT-компиляция. Мы решили рассказать о том, как это будет, зачем это нужно, а также развеять несколько устойчивых мифов, которые сложились вокруг статической и динамической компиляции.
Какая-какая компиляция?
Статическая, или Ahead-Of-Time (AOT) компиляция — это самая обычная компиляция, которую мы привыкли видеть в языке Си. Исходный код превращается в исполняемый, и на выходе получается исполняемый файл, который можно запустить позже. На статическую компиляцию требуется дополнительное время до начала работы программы, отсюда и название. Существует ещё динамическая, или Just-In-Time (JIT) компиляция — она осуществляется прямо во время работы программы, «на лету». Именно она и используется в Java в настоящий момент.
А в Java 9 хотят заменить её на статическую?
Нет. В Java 9 планируют добавить возможность AOT-компилятор в качестве альтернативы (но не замены) существующим инструментам. Утилита будет называться jaotc
. В Java 9 она гарантированно будет работать только для модуля java.base
, который содержит всё необходимое для работы с объектами, потоками и структурами данных — то, без чего не может обойтись ни одно приложение. Исходя из этого, AOT-компиляцию в Java 9 всё ещё можно назвать лишь экспериментальной возможностью.
А зачем это нужно?
AOT-компиляция имеет несколько специфических преимуществ. Во-первых, это защита от декомпиляции. Байткод Java можно без особого труда декомпилировать в код на Java, и, таким образом, взломать программу (которая, например, требует лицензионный ключ). Исполняемый код же можно лишь дизассемблировать, и, думается, любой может сравнить сложность поиска каких-то деталей в коде на Java и ассемблерном коде. Обфускация же далеко не панацея, т.к. она трудно реализуема при активном использовании рефлексии и всё равно не даёт стопроцентной защиты. Во-вторых, стоит обратить внимание на время запуска приложения. Для первого запуска (так называемого «холодного старта») приложению требуется значительное количество времени. Для скомпилированного статически кода на Java стартовое время не отличается от старта аналогичной программы на Си:
То есть, получается, со статической компиляцией мы получим в Java скорость Си?
Нет. Си достигает значительной скорости за счёт многих допущений небезопасного поведения. Например, в случае выхода за границы массива в Си случится segfault (в лучшем случае), а в Java просто вылетит ArrayOutOfBoundsException
. Подобные проверки не бесплатны, за них приходится платить производительностью как в случае динамической компиляции, так и в случае статической.
Неверным также является представление, что Си в целом работает быстрее Java. Так, в Java компилятору доступен весь код всех подключенных библиотек, а значит, он может оптимизировать их работу наиболее выгодным для данного приложения путём. В Си же библиотеки могут подключаться в виде машинного кода, и никакие дополнительные оптимизации для них недоступны.
Так значит, JIT для Java подходит лучше? Это ведь всё-таки динамический язык.
Такое утверждение тоже будет неверным. Оптимизации, которые производит компилятор, могут быть достаточно сложными и ресурсоёмкими, могут требовать итеративного пересчёта и анализа всей программы целиком. Зачастую в процессе оптимизации возникает такое количество дополнительных данных, что хранить их в оперативной памяти невозможно, и требуется их промежуточная запись на диск. Всего этого JIT-компилятор просто не может себе позволить. Очень заметна разница в производительности между JIT-исполняемым кодом и AOT-компилированным, например, при работе с элементами пользовательского интерфейса.
Что-то я совсем запутался. Так что же лучше?
На этот вопрос нельзя дать однозначного ответа. Для разных приложений и для разных целей выбор может быть разным. Главное, что теперь он будет. Конечно, AOT-компиляторы Java существовали и раньше, однако мало кто из них может похвастаться полноценной поддержкой свежих спецификаций Java. Теперь, когда за дело взялись специалисты из Oracle, возможно, ситуация изменится в лучшую сторону. Про AOT-компиляцию Java кода есть отличный доклад Никиты Липского, на который мы в основном и опирались при подготовке данной статьи:
Можно привести пример, в каких ситуациях статическая компиляция будет явно лучше, чем JIT?
При разработке для встраиваемых систем и мобильных платформ, скорее всего, AOT-компиляция будет лучшим выбором. Встраиваемые системы чаще всего не обладают теми же вычислительными мощностями, что и настольные компьютеры или сервера, а чем слабее железо, тем дороже динамическая компиляция. В случае с мобильными устройствами решающую роль играет другой фактор — нагрузка на аккумулятор. Динамическая компиляция требует много большего расхода энергии, чем выполнение уже скомпилированного кода. Так, для iOS политика распространения приложений вовсе запрещает любую динамическую загрузку кода, поэтому Java фактически невозможно использовать для программирования под устройства Apple.
А можно больше подробностей про то, что именно мы увидим в Java 9?
Мы увидим утилиту jaotc
, которая сможет создавать нативные исполняемые файлы для Linux x64, основанные на модуле java.base
.
Выглядеть это будет примерно следующим образом. Мы можем создать ELF-файл:
jaotc --output libHelloWorld.so HelloWorld.class
Затем подключить его в качестве библиотеки для исполнения другого кода:
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
Причём (по крайней мере, в этом релизе) для AOT-компиляции и для запуска должны использоваться одни и те же параметры:
jaotc -J-XX:+UseParallelGC -J-XX:-UseCompressedOops --output libHelloWorld.so HelloWorld.class java -XX:+UseParallelGC -XX:-UseCompressedOops -XX:AOTLibrary=./libHelloWorld.so HelloWorld
Больше технических деталей можно узнать на сайте OpenJDK.
В статье использовано изображение из Takipi Blog
Оптимизации генерации кода в JIT-компиляторе виртуальной машины Java
Похожие презентации:
Генерация и оптимизация кода
Виртуальная машина Java
Как выбрать язык программирования?
Введение в Java. (Урок 1)
Java-технологии
Высокопроизводительные вычисления
Программирование на Java. Введение
Распараллеливание на компьютерах с общей памятью
Код. Компилятор
Программирование на языке Java. Введение. (Лекция 1)
1. Дипломная работа «Оптимизации генерации кода в JIT-компиляторе виртуальной машины Java»
Санкт-Петербургский государственный университетМатематико-механический факультет
Кафедра системного программирования
Дипломная работа
«Оптимизации генерации кода в JITкомпиляторе виртуальной машины
Java»
Научный руководитель
Куксенко С.В.
Рецензент
Салищев С.И.
Выполнил
Проничкин Дмитрий 544гр.
2008
2. Актуальность работы
• Постоянное совершенствование микроархитектурыпроцессоров
• Особенности новой микроархитектуры Intel Core
• Увеличение важности производительности front-end процессора
• Работа front-end влияет не только на производительность, но и
на флуктуацию при ее измерении
• Отсутствие работ, учитывающих данные особенности
микроархитектуры Core, даже в Intel Compiler
3.
РезультатыРазработаны идеи и эвристики для оптимизации линеаризации и
выравнивания кода
Опробована схема удаления ветвлений в коде
В генераторе кода JIT-компилятора виртуальной машины Apache
Harmony реализованы улучшения линеаризации и выравнивания
кода, удаления ветвлений
Получен прирост производительности на микротестах и популярных
бенчмарках, таких как SciMark (Monte Carlo – прирост 60%)
Увеличена стабильность метрик производительности
Изменения приняты и интегрированы в Apache Harmony
4. Apache Harmony
• Открытая реализация виртуальной машиныJava
• JIT-компилятор Jitrino.OPT – оптимизирующий
компилятор с возможностью профилировки и
перекомпиляции
• Особенности front-end микроархитектуры
Core не учтены
5. Выравнивание кода
• Отсутствие trace cache по сравнению смикроархитектурой NetBurst
• Линия выборки (fetch line) 16 байт
• Особенности предсказателя переходов
• Дополнительная возможность процессора – loop
stream detector
• Все эти особенности учтены и разработана эвристика
для выравнивания кода
6.
Линеаризация кода• Расположение базовых блоков графа потока управления влинейном порядке
• Алгоритм “bottom-up”, имеющий много свойств, положительных для
front-end процессора
• Найдены
возможности для
улучшения под
микроархитектуру
Core
• Разработана
эвристика для
оптимизации
алгоритма
7. Удаление ветвлений
• Все современные микроархитектуры – конвейерныесуперскалярные
• Неправильно предсказанный условный переход
приводит к задержке работы конвейера
• Иногда можно удалить ветвление, заменив его на
более сложные, но линейные вычисления
• Схема удаления ветвлений опробована на бенчмарке
SciMark, получен значительный прирост
производительности
English Русский Правила
JIT в Java | Java JIT
следующий → ← предыдущая Когда мы пишем программу на любом языке программирования, она требует преобразования этого кода в машинопонятную форму, потому что машина понимает только двоичный язык. В зависимости от языков программирования компилятор различается. Компилятор — это программа, которая преобразует язык высокого уровня в код машинного уровня. Язык программирования Java использует компилятор с именем javac . Он преобразует код языка высокого уровня в машинный код (байт-код). JIT — это часть JVM, оптимизирующая производительность приложения. JIT означает Java-In-Time Compiler . JIT-компиляция также известна как динамическая компиляция. В этом разделе мы узнаем , что такое JIT в Java, его работу, и фазы JIT-компилятора .Что такое JIT в Java? JIT на Java является неотъемлемой частью JIT-компиляция включает два подхода AOT (компиляция с опережением времени) и интерпретация для перевода кода в машинный код. Компилятор AOT компилирует код в собственный машинный язык (такой же, как обычный компилятор). Он преобразует байт-код виртуальной машины в машинный код. Компиляторы JIT выполняют следующие оптимизации:
Преимущества JIT-компилятора
Недостатки JIT-компилятора
Работа компилятора JITЕсли переменная среды JIT-компилятора установлена правильно, JVM считывает файл .class (байт-код) для интерпретации, после чего передает JIT-компилятору для дальнейшей обработки. Получив байт-код, JIT-компилятор преобразует его в собственный код (машиночитаемый код).
Таким образом, компилятор JIT повышает производительность собственного приложения. Мы можем понять работу JIT-компилятора с помощью следующей блок-схемы. На следующем рисунке показана функциональная взаимосвязь JIT-компилятора с JRE и JVM. Уровни оптимизацииОн также известен как уровень оптимизации . Каждый уровень обеспечивает определенный уровень производительности. Компилятор JIT обеспечивает следующий уровень оптимизации:
Уровни оптимизации по умолчанию и начальный уровень теплый . Мы получаем лучшую производительность, если уровень оптимизации выше, но это увеличивает стоимость памяти и процессора. На более высоком уровне оптимизации виртуальная машина использует поток с именем , выборка . Он определяет методы, выполнение которых занимает много времени. Высший уровень оптимизации включает в себя следующие техники:
Приведенные выше методы используют больше памяти и ЦП для повышения производительности приложения Java. Это увеличивает стоимость компиляции, но компенсирует производительность. Следующая темаКак очистить экран в Java ← предыдущая следующий → |
Для видео Присоединяйтесь к нашему каналу Youtube: Присоединяйтесь сейчас
Обратная связь
- Отправьте свой отзыв на [email protected]
Помогите другим, пожалуйста, поделитесь
Изучите последние учебные пособия
Подготовка
Современные технологии
Б.
Тех / МСАКомпилятор Just In Time — GeeksforGeeks
Улучшить статью
Сохранить статью
Нравится Статья
Шреяш Шарма 3
автор
1 опубликованная статья
Улучшить статью
Сохранить статью
Нравится Статья
JIT-компилятор или JIT-компилятор является важной частью JRE (Java Runtime Environment), которая отвечает за оптимизацию производительности Java-приложений во время выполнения. Компилятор является одним из ключевых аспектов при определении производительности приложения для обеих сторон, то есть для конечного пользователя и разработчика приложения. Давайте более подробно рассмотрим компилятор Just In Time на Java.
Байт-код — одна из наиболее важных функций Java, которая помогает в кросс-платформенном выполнении. Способ преобразования байт-кода в собственный машинный язык для выполнения оказывает огромное влияние на его скорость. Эти байт-коды должны быть интерпретированы или скомпилированы в соответствующие машинные инструкции в зависимости от архитектуры набора инструкций.
JIT-компилятор может выполнять некоторые простые оптимизации при компиляции серии байт-кода в родной машинный язык. Некоторыми из этих оптимизаций, выполняемых компиляторами JIT, являются анализ данных, сокращение доступа к памяти за счет выделения регистров, перевод операций со стеком на операции с регистрами, устранение общих подвыражений и т. д. Чем выше степень оптимизации, тем больше времени JIT компилятор тратит на этапе выполнения. Следовательно, он не может позволить себе выполнить все оптимизации, на которые способен статический компилятор, из-за дополнительных накладных расходов, добавляемых ко времени выполнения, и, кроме того, его представление о программе также ограничено.
Работа с JIT-компиляторомJava следует объектно-ориентированному подходу, поэтому он состоит из классов. Они составляют байт-код, который не зависит от платформы и выполняется JVM в различных архитектурах.
- Во время выполнения JVM загружает файлы классов, определяется семантика каждого из них и выполняются соответствующие вычисления. Использование дополнительного процессора и памяти во время интерпретации приводит к тому, что Java-приложение работает медленнее по сравнению с собственным приложением.
- JIT-компилятор помогает повысить производительность программ Java за счет компиляции байт-кода в собственный машинный код во время выполнения.