Как работает Java:

  • Java компилирует код и преобразует его в байтовый код (.class)
  • JVM интерпретирует байтовые коды и преобразует их в коды машинного уровня, чтобы его можно было запускать на любом компьютере.

Байт-код в машинный код:

  • Байт-код преобразуется в код машинного уровня с использованием словаря инструкций (байтовый в m / c), поскольку разные типы машин (например, Ubuntu, mac, windows и т. Д.) Имеют разные типы набора инструкций.
  • Переводчик очень быстро запускает и загружает приложение.
  • Одна из проблем заключается в том, что интерпретатор не выполняет никаких оптимизаций, потому что один и тот же байтовый код каждый раз преобразуется в машинный код.

  • Для решения этой проблемы используется компилятор C1, который использует кеш кода.

Компилятор C1:

  • Поэтому, когда интерпретатор интерпретирует байтовый код, он использует счетчик того, сколько раз один и тот же байтовый код преобразуется в машинный код, который сохраняется в кеше кода.
  • Когда счетчик достигает порогового значения, компилятор C1 компилирует коды и сохраняет их в кеше кода, чтобы при выполнении тех же байт-кодов они были получены из кеша кода.
  • Кэш кода - это область памяти, отдельная от кучи JVM, которая содержит весь байт-код JVM для метода, скомпилированного в собственный код, каждый из которых называется nmethod1. Здесь хранятся JIT-скомпилированные методы.
  • Это также называется JIT (точно вовремя) компиляцией.

  • Размер кэша кода по умолчанию составляет 240 МБ в java 8, но мы можем установить другое значение, используя флаг -XReservedCodeCacheSize.
  • Порог компиляции по умолчанию - 1500 для компилятора C1.

Компилятор C2:

  • Через некоторое время, когда JVM работает в течение некоторого времени, она начинает в фоновом режиме собирать статистику о том, как выполняется код, что называется профилированием кода. Он создает графы потока управления (пути кода). Он пытается найти самые горячие пути кода, как только у него будет достаточно статистики, после чего JVM попросила компилятор C2 выполнить оптимизацию на самых горячих путях кода.
  • Он также хранит оптимизированный код в кэше кода.

Оптимизация, выполняемая C2:

  • Мертвый код
  • Анализ побега
  • Петли
  • Встраивание методов
  • Нулевой контроль Устранение

и т.д. используются компилятором C2 для оптимизации самого горячего кода

Подробнее о C1 и C2:

  • Два компилятора, C1 и C2, работают параллельно и продолжают оптимизацию кода.
  • . C1 предпочтительнее для клиентского приложения, а C2 предпочтительнее для длительно работающих серверных приложений.
  • Многоуровневая компиляция сочетает в себе лучшие возможности обоих компиляторов. Компиляция на стороне клиента обеспечивает быстрое время запуска и быструю оптимизацию, в то время как компиляция на стороне сервера обеспечивает более продвинутую оптимизацию на более поздних этапах цикла выполнения.
  • Когда кэш кода ограничен (его использование приближается к ReservedCodeCacheSize или достигает его), для компиляции большего количества методов JIT сначала должен выбросить некоторые уже скомпилированные методы. Отказ от скомпилированных методов известен как очистка кэша кода.
  • В JAVA 7 у нас есть возможность выбрать оба компилятора.
  • В JAVA 8 оба доступны по умолчанию.

Опережая время, компиляция:

При профилировании вручную или вручную проверяйте поток или дамп памяти из JVM, нам может потребоваться выполнить компиляцию заранее. эта функция включена после JAVA9.

После Java9 у нас есть возможность преобразовать некоторые классы или библиотеки в скомпилированный код перед запуском приложения.

Скомпилируйте класс до:

Прежде чем мы сможем использовать компилятор AOT, нам нужно скомпилировать класс с помощью компилятора Java:

javac <classname>.java

Передайте класс компилятору AOT:

Затем мы передаем получившийся ‹classname› .java компилятору AOT, который находится в том же каталоге, что и стандартный компилятор Java.

jaotc --output <classname>.so <classname>.class

Запуск программы

Затем мы можем выполнить программу во время работы программы, которая нам нужна, чтобы использовать флаг -XX: AOTLibrary, чтобы сообщить JVM для скомпилированного класса AOT.

java -XX:AOTLibrary=./<classname>.so <classname>
  • Мы также можем увидеть, что библиотека была загружена, добавив -XX: + PrintAOT в качестве аргумента JVM.

Вот и все.

Удачного обучения.