[Получить интервью с JVM] Интервьюер: Как выглядит процесс загрузки класса JVM?

Java

процесс загрузки класса

Файлы классов необходимо загрузить в виртуальную машину, прежде чем их можно будет запустить и использовать, так как же виртуальная машина загружает эти файлы классов?

Система загружает файлы типа Class в три основных этапа:Загрузить->Подключить->Инициализировать. Процесс подключения можно разделить на три этапа:Проверить -> Подготовить -> Разобрать.

类加载过程

нагрузка

Первый шаг в процессе загрузки класса в основном завершает следующие три вещи:

  1. Получите двоичный поток байтов, определяющий этот класс по его полному имени класса
  2. Преобразуйте статическую структуру хранения, представленную потоком байтов, в структуру данных времени выполнения области метода.
  3. Создайте объект класса, представляющий класс в памяти, в качестве записи доступа к этим данным в области методов.

Спецификация виртуальной машины намного больше, чем три вышеуказанных пункта, не являются конкретными, поэтому она очень гибкая. Например: «Получить двоичный поток байтов, определяющий этот класс, через полное имя класса» не указывает, где и как его получить. Например, более распространено чтение из ZIP-пакета (основа для форматов JAR, EAR и WAR, которые появятся в будущем), создание других файлов (типичное приложение — JSP) и так далее.

Этап загрузки класса без массива (действие получения двоичного потока байтов класса на этапе загрузки) является наиболее контролируемым этапом. Мы можем выполнить этот шаг, а также настроить загрузчик классов для управления способом получения поток байтов (переопределение загрузчика классовloadClass()метод). Тип массива не создается загрузчиком классов, он создается непосредственно виртуальной машиной Java.

Загрузчик классов и модель родительского делегирования также являются очень важными знаниями, которые будут представлены отдельно в последующих статьях.

Части фазы загрузки и фазы связывания чередуются, и фаза связывания может уже начаться до завершения фазы загрузки.

проверять

验证阶段示意图

Подготовить

Фаза подготовки — это фаза, на которой формально выделяется память для переменных класса и устанавливаются начальные значения для переменных класса., эта память будет выделена в области методов. На этом этапе есть несколько замечаний:

  1. В настоящее время выделение памяти включает только переменные класса (статические), а не переменные экземпляра.Переменные экземпляра будут выделены в куче Java вместе с объектом при создании экземпляра объекта.
  2. Установленное здесь начальное значение «обычно» является нулевым значением по умолчанию для типа данных (например, 0, 0L, null, false и т. д.), например, мы определяемpublic static int value=111, то начальное значение переменной value на этапе подготовки равно 0 вместо 111 (значение будет присвоено только на этапе инициализации). Особые случаи: например, добавление ключевого слова fianl к переменной значения.public static final int value=111, то значению значения фазы подготовки присваивается значение 111.

Нулевые значения для примитивных типов данных:

基本数据类型的零值

Разобрать

Фаза разрешения — это процесс, посредством которого виртуальная машина заменяет символические ссылки в пуле констант прямыми ссылками. Действие синтаксического анализа в основном выполняется для 7 типов символических ссылок, таких как класс или интерфейс, поле, метод класса, метод интерфейса, тип метода, дескриптор метода и квалификатор вызова.

Символическая ссылка — это набор символов для описания цели, который может быть любым литералом.прямая цитатаЯвляется указателем непосредственно на цель, относительным смещением или маркером, который косвенно расположен на цели. Когда программа действительно работает, одних только символических ссылок недостаточно, например: когда программа выполняет метод, система должна точно знать, где этот метод находится. Виртуальная машина Java подготавливает таблицу методов для каждого класса для хранения всех методов класса. Когда вам нужно вызвать метод класса, вы можете вызвать метод напрямую, если вы знаете смещение метода в боковой таблице. Разрешив ссылку на символ операции, ее можно напрямую преобразовать в позицию целевого метода в таблице методов класса, чтобы метод можно было вызвать.

Подводя итог, можно сказать, что фаза синтаксического анализа — это процесс, в котором виртуальная машина заменяет символические ссылки в пуле констант прямыми ссылками, то есть для получения указателей или смещений классов, полей и методов в памяти.

инициализация

Инициализация — это последний шаг загрузки класса, а также фактическое выполнение программного кода Java (байт-кода), определенного в классе.Фаза инициализации заключается в выполнении конструктора класса.<clinit> ()процесс метода.

за<clinit>()Вызовы методов, виртуальная машина сама обеспечивает свою безопасность в многопоточной среде. потому что<clinit>()Метод является потокобезопасным с блокировками, поэтому инициализация класса в многопоточной среде может привести к взаимоблокировкам, и такие взаимоблокировки трудно обнаружить.

Для фазы инициализации виртуальная машина строго указывает, что есть только 5 случаев, в которых класс должен быть инициализирован:

  1. При встрече с четырьмя прямыми инструкциями кода new , getstatic, putstatic или invokestatic, такими как создание нового класса, чтение статического поля (без окончательного изменения) или вызов статического метода класса.
  2. использоватьjava.lang.reflectКогда метод пакета делает рефлексивный вызов класса, если класс не инициализирован, его инициализацию необходимо запустить.
  3. Инициализируйте класс, если его родительский класс не был инициализирован, сначала инициируйте инициализацию родительского класса.
  4. Когда запускается виртуальная машина, пользователю необходимо определить основной класс (тот, который содержит основной метод) для выполнения, и виртуальная машина сначала инициализирует этот класс.
  5. При использовании динамического динамического языка JDK1.7, если последней проанализированной структурой экземпляра MethodHandle является дескриптор метода REF_getStatic, REF_putStatic, REF_invokeStatic, и этот дескриптор не инициализирован, его необходимо сначала инициализировать с помощью триггера.

Ссылаться на

  • "Глубокое понимание виртуальной машины Java"
  • «Практическая виртуальная машина Java»
  • docs.Oracle.com/JavaColor/spec…

Рекомендация проекта с открытым исходным кодом

Другие рекомендации автора по проектам с открытым исходным кодом:

  1. JavaGuide: [Изучение Java + руководство для интервью] Обложка, содержащая основные знания, которые необходимо освоить большинству Java-программистов.
  2. springboot-guide: Учебное пособие по Spring Boot, подходящее для начинающих и опытных разработчиков (поддержка в свободное время, добро пожаловать в совместную поддержку).
  3. programmer-advancement: Я думаю, некоторые хорошие привычки, которые должны быть у техников!
  4. spring-security-jwt-guide:Начинать с нуля! Spring Security с JWT (включая проверку авторизации) бэкэнд-часть кода.

публика