GitHub 2.6k ЗвездаПуть к тому, чтобы стать Java-инженером, почему бы тебе не прийти и не узнать?
GitHub 2.6k ЗвездаПуть к тому, чтобы стать Java-инженером, ты правда не хочешь узнать?
GitHub 2.6k ЗвездаПуть к тому, чтобы стать Java-инженером, ты действительно уверен, что не хочешь узнать?
существует"Компиляция и декомпиляция кода Java", есть введение в компиляцию и декомпиляцию языка Java. мы можем пройтиjavac
Команда компилирует исходный код Java-программы в байт-код Java, который мы часто называем файлом класса. Это компиляция в обычном для нас понимании.
Однако байт-код не является машинным языком, и для того, чтобы машина могла выполняться, байт-код должен быть переведен в машинные инструкции. Этот процесс выполняется виртуальной машиной Java, и этот процесс также называется компиляцией. представляет собой более глубокий уровень компиляции.
В соответствии с принципом компиляции перевод исходного кода в машинные инструкции обычно проходит через следующие важные этапы:
По разным задачам компоненты компилятора можно разделить на передний конец (Front End) и задний конец (Back End).
Внешняя компиляция в основном относится к частям, связанным с исходным языком, но не связанным с целевой машиной, включая лексический анализ, синтаксический анализ, семантический анализ и генерацию промежуточного кода.
Бэкэнд-компиляция в основном относится к части, связанной с целевой машиной, включая оптимизацию кода и генерацию целевого кода.
мы можем поставить.java
файл, скомпилированный в.class
Процесс компиляции называется предварительной компиляцией. поставить генерала.class
Процесс компиляции преобразования файлов в машинные инструкции называется внутренней компиляцией.
Компиляция внешнего интерфейса на Java
Внешняя компиляция в основном относится к частям, связанным с исходным языком, но не связанным с целевой машиной, включая лексический анализ, синтаксический анализ, семантический анализ и генерацию промежуточного кода.
что мы знаемjavac
Компиляция — это предварительная компиляция. В дополнение к этому, многие используемые нами IDE, такие как eclipse, idea и т. д., имеют встроенные интерфейсные компиляторы. Основная функция состоит в том, чтобы.java
код в.class
код.
лексический анализ
Фаза лексического анализа является первой фазой процесса компиляции. Задача этого этапа — прочитать исходную программу посимвольно слева направо и преобразовать последовательность символов в последовательность токенов. Токен здесь — это строка, наименьшая единица, из которой состоит исходный код. Во время этого процесса лексер также классифицирует токены.
Лексические анализаторы обычно не заботятся о связи между токенами (в категории синтаксического анализа), например: лексический анализатор может распознавать скобки как токены, но не гарантирует, совпадают ли скобки.
Разбор
Задача грамматического анализа состоит в объединении последовательностей слов в различные грамматические фразы на основе лексического анализа, такого как «программа», «утверждение», «выражение» и т. д. Программа грамматического анализа оценивает, является ли исходная программа структурно правильной. Источник Структура программы описывается контекстно-свободной грамматикой.
Семантический анализ
Семантический анализ является логической стадией процесса компиляции, и задачей семантического анализа является выполнение контекстно-зависимой проверки характера и типа структурно правильных исходных программ. Семантический анализ проверяет исходную программу на наличие семантических ошибок и собирает информацию о типе для этапа генерации кода.
Важной частью семантического анализа является проверка типов. Например, многие языки требуют, чтобы индексы массива были целыми числами.Если в качестве индексов используются числа с плавающей запятой, компилятор должен сообщить об ошибке. В качестве другого примера, многие языки допускают определенные преобразования типов, называемые автоматическими преобразованиями типов.
Генерация промежуточного кода
После завершения синтаксического и семантического анализа исходной программы многие компиляторы генерируют явное низкоуровневое или похожее на машинный язык промежуточное представление. Это промежуточное представление имеет два важных свойства: 1. Его легко сгенерировать, 2. Его можно легко перевести на язык целевой машины.
В Яве,javac
Результатом выполнения является получение байт-кода, и этот байт-код фактически является неким промежуточным кодом.
PS: Знаменитая операция деконструкции сахара также выполняется в javac.
Компиляция бэкенда на Java
Во-первых, как мы все знаем, обычноjavac
Скомпилируйте исходный код программы и преобразуйте его в байт-код Java.JVM переводит его в соответствующие машинные инструкции, интерпретируя байт-код, считывает его один за другим, а также интерпретирует и переводит его один за другим. Очевидно, что после интерпретации и выполнения его скорость выполнения будет намного ниже, чем у исполняемой двоичной программы байт-кода. Это функция **интерпретатора** традиционной JVM. Для решения этой проблемы эффективности необходимо введениеJITТехнология.
Программа JAVA по-прежнему интерпретируется и выполняется интерпретатором. Когда JVM обнаруживает, что метод или блок кода выполняется очень часто, она будет рассматривать это как «горячий код». Затем JIT поставит какой-нибудь «горячий код»переводитьстоимость машинного кода, связанного с локальной машиной, и выполнениеоптимизация, а затем поместите переведенный машинный кодтайникдо следующего использования.
В виртуальной машине HotSpot есть два встроенных JIT-компилятора: Client Complier и Server Compiler, которые используются на стороне клиента и на стороне сервера соответственно.В настоящее время основная виртуальная машина HotSpot использует интерпретатор для прямой работы с одним из компиляторы по умолчанию.
Когда JVM выполняет код, он не сразу начинает компилировать код. Во-первых, если сам код будет выполняться только один раз в будущем, то компиляция, по сути, является пустой тратой усилий. Потому что перевод кода в байт-код java намного быстрее, чем компиляция этого кода и его выполнение. Вторая причина — оптимизация: чем больше JVM выполняет метод или проходит цикл, тем лучше она понимает структуру кода, и JVM вносит соответствующие оптимизации при компиляции кода.
На машине выполнитьjava -version
Вы можете увидеть, какой режим JIT находится в JDK, который вы установили, с помощью команды:
На приведенном выше рисунке показан jdk1.8, установленный на моей машине.Как вы можете видеть, это серверная компиляция.Однако следует отметить, что независимо от того, является ли это клиентским компилятором или серверным компилятором, комбинация интерпретатора и компилятора представляет собой смешанный режим. , который является смешанным режимом на приведенном выше рисунке.
Обнаружение горячих точек
Как мы уже говорили выше, чтобы запустить JIT, вам сначала нужно определить горячий код. В настоящее время основным методом идентификации кода горячих точек является обнаружение горячих точек, которое имеет следующие два типа:
1. Обнаружение горячих точек на основе выборки (Обнаружение горячих точек на основе выборок): Периодически определяйте вершину стека каждого потока и обнаруживайте, что метод часто находится на вершине стека, что считается методом горячих точек. Преимущество в простоте, недостаток в невозможности точно подтвердить популярность метода. Легко помешать обнаружению горячих точек из-за блокировки потока или по другим причинам.
2. Обнаружение горячих точек на основе счетчика. Виртуальная машина, использующая этот метод, устанавливает счетчик для каждого метода, даже блока кода, и подсчитывает время выполнения метода.Если метод превышает пороговое значение, он считается горячим методом и запускает JIT-компиляцию.
В виртуальной машине HotSpot используется второй метод — метод обнаружения горячих точек на основе счетчиков, поэтому он подготавливает два счетчика для каждого метода: счетчик вызова метода и счетчик заднего края.
Счетчик методов. Как следует из названия, это счетчик, который записывает количество вызовов метода.
Счетчик задней кромки. это счетчик, который записывает количество запусков for или while в методе.
Оптимизация компиляции
Как упоминалось ранее, помимо функции кэширования, JIT также выполняет различные оптимизации кода. Говоря об этом, я должен восхищаться разработчиками HotSpot, они действительно всесторонне оптимизируют код в JIT.
Вот краткий ответ, чтобы упомянуть несколько методов оптимизации, которые я считаю более важными, и я не собираюсь расширять их напрямую.Если читателям интересно, я напишу статью, чтобы представить их отдельно позже.
Анализ побега, Устранение блокировки, Инфляция блокировки, Встраивание методов, Устранение нулевой проверки, Устранение обнаружения типа, Устранение общего подвыражения