загрузка класса
что такое загрузка класса
Загрузка класса делает следующее:
- Прочитайте двоичные данные в файле .class класса в память и поместите их в область методов области данных времени выполнения.
- Затем создайте объект java.lang.Class в области кучи, который используется для инкапсуляции структуры данных класса в области методов.
Конечный продукт загрузки класса:
Создан объект класса, расположенный в области кучи, объект вторичного класса инкапсулирует структуру данных класса в области метода и предоставляет программисту Java интерфейсом для доступа к структуре данных в области метода.
время загрузки класса
Понять, что такое загрузка класса, и когда класс будет загружен?
- Загрузчику классов не нужно ждать, пока класс будет «активно использоваться в первый раз», прежде чем загружать его, то есть ему не нужно ждать, пока загрузится новый класс.
- Спецификация JVM позволяет загрузчику классов предварительно загружать класс, когда ожидается, что он будет использоваться.Если файл .class отсутствует или во время процесса предварительной загрузки возникает ошибка, загрузчик классов должен активно использует класс Сообщить об ошибке (LinkageError)
- Если отсутствующий класс .class не использовался программой активно, загрузчик классов не сообщит об ошибке.
Как загрузить файлы .class
- Загрузка напрямую из локальной системы
- Загрузите файл .class из сети
- Загрузите файлы .class из архивов, таких как zip, jar и т. д.
- Извлечь файлы .class из проприетарной базы данных
- Динамически компилировать исходные файлы Java в файлы .class
жизненный цикл класса
Основные моменты, которые нужно знать:
- Процесс загрузки класса включает пять этапов: загрузка, проверка, подготовка, синтаксический анализ и инициализация.Иногда три этапа проверки, подготовки и синтаксического анализа также называют этапом ссылки.
- Среди них определяется порядок четырех этапов загрузки, проверки, подготовки и инициализации, при этом этап синтаксического анализа не является обязательным, в некоторых случаях он может начинаться после этапа инициализации, это необходимо для поддержки привязки языка Java во время выполнения. фиксированный (также известный как динамическое связывание или позднее связывание).
- Также обратите внимание на несколько этапов здесьНачинайте последовательно, а не продолжайте или заканчивайте последовательно, потому что эти фазы обычно чередуются и смешиваются, обычно вызывая или активируя одну фазу во время выполнения другой.
нагрузка
Загрузка — это первый этап процесса загрузки класса. Он в основном находит и загружает двоичные данные класса. На этапе загрузки JVM необходимо выполнить следующие три действия:
-
Получить поток двоичных байтов, определенный классом, по его полному имени.
-
Преобразуйте статическую структуру хранения, представленную этим потоком байтов, в структуру данных времени выполнения области метода.
-
Объект java.lang.Class, представляющий этот класс, создается в куче Java как запись доступа к данным в области метода.
По сравнению с другими этапами загрузки классов, этап загрузки (точнее, действие по получению бинарного потока байтов класса на этапе загрузки) является наиболее контролируемым этапом, поскольку разработчики могут использовать загрузку классов, предоставляемую системой. Вы можете использовать загрузчик классов для завершения загрузки или настроить свой собственный загрузчик классов для завершения загрузки.
После завершения фазы загрузки двоичный поток байтов вне виртуальной машины сохраняется в области методов в соответствии с форматом, требуемым виртуальной машиной, а также создается объект класса java.lang.Class в куче Java, так что Объекты получают доступ к этим данным в области методов.
проверять
Проверка — это первый шаг на этапе связывания.Это необходимо для обеспечения правильности загруженных классов.
Цель этого этапа — убедиться, что информация, содержащаяся в байтовом потоке Class-файла, соответствует требованиям текущей виртуальной машины и не будет угрожать безопасности самой виртуальной машины.
Этап проверки будет примерно состоять из четырех этапов инспекционных действий:
-
Проверка формата файла: проверьте, соответствует ли поток байтов спецификации формата файла класса, например: начинается ли он с 0xCAFEBABE, находятся ли основной и дополнительный номера версий в пределах диапазона обработки текущей виртуальной машины, находятся ли константы в постоянный пул имеет неподдерживаемые типы.
-
Проверка метаданных: выполните семантический анализ информации, описанной байт-кодом (примечание: сравните семантический анализ фазы компиляции javac), чтобы убедиться, что описанная информация соответствует требованиям спецификации языка Java; например: есть ли у этого класса родитель класс, кроме java вне .lang.Object.
-
Проверка байт-кода: посредством анализа потока данных и потока управления определено, что семантика программы является законной и логичной.
-
Проверка символьной ссылки: гарантирует, что действия по разрешению выполняются правильно.
Фаза проверки очень важна, но не обязательна, она не влияет на время работы программы., если указанный класс неоднократно проверялся, можно использовать параметр -Xverifynone, чтобы отключить большинство мер проверки класса и сократить время загрузки класса виртуальной машины.
Подготовить
На этапе подготовки выделяется память для статических переменных класса (Обратите внимание, что это статическая переменная),Эта память будет выделена в области методаи инициализируйте его значением по умолчанию.
На этом этапе есть несколько замечаний:
-
В настоящее время для выделения памяти выделяются только переменные класса (статические), а не переменные экземпляра.Переменные экземпляра будут выделены в куче Java вместе с объектом при создании экземпляра объекта.
-
Установленное здесь начальное значение обычно представляет собой нулевое значение по умолчанию для типа данных (например, 0, 0L, null, false и т. д.), а не значение, которое явно назначается в коде Java.
Возьмите каштан:
假设一个类变量的定义为:public static int value = 3;
那么变量value在准备阶段过后的初始值为0,而不是3,把value赋值为3的动作将在初始化阶段才会执行。
-
Для базовых типов данных, переменных класса (статических) и глобальных переменных, если они используются напрямую без их явного присвоения, система присвоит им значение по умолчанию, равное нулю, в то время как для локальных переменных их необходимо использовать перед использованием. значение для него, иначе он не будет передан во время компиляции.
-
Для констант, измененных как статическими, так и финальными, они должны быть явно назначены при объявлении, иначе они не будут переданы во время компиляции.
-
Константе, которая изменяется только с помощью final, может быть либо явно присвоено значение при ее объявлении, либо ей может быть явно присвоено значение при инициализации класса (т. е. конструктор) Короче говоря, ей должно быть явно присвоено значение перед использованием. , система не присваивает ему значение по умолчанию, равное нулю.
-
Для ссылки на ссылочный тип данных, такой как ссылка на массив, ссылка на объект и т. д., если она используется напрямую без явного присвоения, система присвоит ей нулевое значение по умолчанию, то есть null.
-
Если при инициализации массива каждому элементу массива не присвоено значение, элементам в нем будет присвоено нулевое значение по умолчанию в соответствии с соответствующим типом данных.
-
Если свойство ConstantValue существует в таблице свойств поля поля класса, т.е.Измененное как final, так и static, значение переменной будет инициализировано значением, указанным свойством ConstValue на этапе подготовки.
Возьмите каштан:
假设上面的类变量value被定义为: public static final int value = 3;
编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为3。我们可以理解为static final常量在编译期就将其结果放入了调用它的类的常量池中
Разобрать
Работа, выполняемая на этапе синтаксического анализа, заключается в преобразовании символических ссылок в классе в прямые ссылки.
Действие синтаксического анализа в основном выполняется для 7 типов символических ссылок, а именно класса или интерфейса, поля, метода класса, метода интерфейса, типа метода, дескриптора метода и квалификатора сайта вызова. Символическая ссылка — это набор символов для описания цели, который может быть любым литералом.
Прямая ссылка — это указатель непосредственно на цель, относительное смещение или дескриптор, который косвенно расположен на цели.
инициализация
Инициализация, присвоение правильных начальных значений статическим переменным класса, JVM отвечает за инициализацию класса, в основном за инициализацию переменных класса.
Есть два способа инициализировать переменные класса в Java:
-
Укажите начальное значение при объявлении переменной класса
-
Используйте статические блоки кода для присвоения начальных значений переменным класса
Этапы инициализации JVM
-
Если класс не загружен и не связан, программа сначала загрузит и свяжет класс
-
Если прямой родительский класс класса не был инициализирован, сначала инициализируйте его прямой родительский класс.
-
Если в классе есть операторы инициализации, система выполняет эти операторы инициализации по очереди.
Время инициализации класса:
Только когда класс активно используется, класс будет инициализирован. Обратите внимание, что это отличается от загрузки класса. Активное использование класса включает следующие шесть:
-
Создать экземпляр класса, то есть по-новому
-
Доступ к статической переменной класса или интерфейса или присвоение значения статической переменной
-
вызов статического метода класса
-
Отражение (например, Class.forName("com.shengsiyuan.Test"))
-
Когда инициализируется подкласс класса, его родительский класс также будет инициализирован.
-
Класс, отмеченный как класс запуска (тест Java), когда запускается виртуальная машина Java, напрямую использует команду java.exe для запуска основного класса.
конец жизненного цикла
В следующих случаях виртуальная машина Java завершит свой жизненный цикл
-
Выполняется метод System.exit()
-
Выполнение программы завершается нормально
-
Программа сталкивается с исключением или ошибкой во время выполнения и аварийно завершается
-
Процесс виртуальной машины Java прерван из-за ошибки операционной системы