Обзор

Виртуальная машина Java (JVM) - это виртуальная машина, которая позволяет компьютеру выполнять скомпилированный байт-код. Это было введено в 1994 году компанией Sun Microsystems. Виртуальные машины можно разделить на два набора.

  • Системная виртуальная машина: одна или несколько аппаратных систем, которые создают несколько рабочих сред, и они полностью независимы.
  • Виртуальная машина на основе приложений: программное приложение, которое создает несколько платформ для запуска других программ. Это также известно как виртуальная машина на основе процессов.

JVM относится к категории виртуальных машин на основе приложений. В основном Java Development Kit (JDK) поставляется с Java Runtime Environment (JRE), и когда вы устанавливаете Java на свой компьютер, JRE развертывает некоторые коды для создания экземпляров JVM на основе используемой вами платформы. В противном случае вы можете получить JRE вместо JDK, но JDK рекомендуется разработчикам, поскольку он предоставляет возможности для компиляции кода и его выполнения. На рисунке 1. показана общая архитектура JVM.

Как правило, байт-код находится в шестнадцатеричном формате со строками операндов-операндов, и экземпляр JVM может интерпретировать или скомпилировать этот байт-код в машиночитаемый язык. Экземпляр JVM создается после получения скомпилированного байт-кода с помощью компилятора javac, и он закрывается, когда все потоки, не являющиеся демонами, закрываются внутри пула потоков или экземпляр JVM вызывает метод выхода во время работы программы.

Компоненты JVM

Как показано на рисунке 2, JVM представляет собой композицию из загрузчика классов, области памяти и механизма выполнения. Давайте подробно объясним, что делает каждый компонент.

Загрузчик классов

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

  • Загрузка: когда загрузчик классов загружает класс в область памяти, он считывает некоторую информацию на основе классов, включая полное имя класса, сведения о статических переменных / модификаторах / информации о методах и т. Д., Тип (перечисление / класс / интерфейс), и непосредственный родитель. После этого создаются объекты с типом класса для каждого класса и сохраняются эти созданные объекты в куче.
  • Связывание: выполняет функции, вызываемые, проверка, подготовка и разрешение. При проверке убедитесь в правильности компилятора и правильности структуры и формата файла класса. Эти шаги выполняются верификатором байт-кода, и если файл класса не удовлетворяет указанным выше трем условиям, верификатор байт-кода выдает ошибку времени выполнения, называемую java.lang.VerifyError. Затем выполняется подготовка, и этим присваиваются значения по умолчанию для статических членов, объявленных внутри класса. Наконец, при разрешении заменяет определенные пользователем ссылки или объекты точными адресами ячеек памяти, которые хранятся в куче.
  • Инициализация: отвечает за инициализацию статических переменных точными значениями и выполнение статических блоков, объявленных внутри класса (если есть). Этот процесс должен завершиться перед активным использованием класса.

Область памяти

Как показано на рисунке 3, это композиция из области метода, области кучи, области стека, регистров ПК и области собственных методов. Итак, давайте проясним назначение каждой области.

  • Область метода: это общий ресурс для каждого экземпляра JVM, и потоки JVM совместно используют эту же область памяти. Здесь содержится информация о классе, включая данные поля, данные метода, размер переменной и т. Д.
  • Область кучи: как область метода, она также создается для каждого экземпляра JVM и отвечает за хранение информации об объектах, созданных на этапе загрузки.
  • Область стека: это не общий ресурс. Для каждого потока JVM, когда поток запускается, создается отдельная область стека для хранения информации, относящейся к каждому методу в потоке и их локальным переменным в виде кадров стека.
  • Регистры ПК: это распределение также создается для каждого потока JVM и отвечает за хранение информации о методах следующего выполнения. Но это сохраняет только информацию о методах Java и не содержит никакой информации о собственных или других методах.
  • Область собственных методов: выделение области собственных методов создается для каждого потока и содержит информацию о собственных методах (если таковые имеются).

Механизм исполнения

Здесь происходит исполнение байт-кода. Сюда входят три основных компонента для выполнения классов Java.

  • Интерпретатор: задача этого компонента - читать и преобразовывать байт-код в машиночитаемый код и выполнять каждую инструкцию одну за другой. Следовательно, это может быстро интерпретировать строку байт-кода, но требует много времени для ее выполнения.
  • JIT-компилятор (Just in Time Compiler): когда один метод вызывается несколько раз, интерпретатору необходимо повторно выполнять этот конкретный набор инструкций. Это отнимает много времени и замедляет процесс выполнения. Чтобы справиться с этой ситуацией, был представлен JIT-компилятор. Компилятор JIT напрямую преобразует байт-код в машинный код (машинный код), выполняя при этом определенные простые методы оптимизации, включая хранение скомпилированных собственных кодов частых инструкций внутри кеша. Это называется адаптивной компиляцией и используется в виртуальных машинах Oracle Hotspot.
  • Сборщик мусора: это поток демона, который отвечает за освобождение памяти кучи путем уничтожения недостижимых объектов, объявленных внутри класса. Это активируется, когда куча заполнена.

В дополнение к этим трем компонентам внутри JVM есть еще два компонента, которые называются Java Native Interface (JNI) и Native Method Libraries.

  • Собственный интерфейс Java (JNI): он взаимодействует с библиотеками собственных методов, которые необходимы для выполнения, и позволяет JVM вызывать их.
  • Библиотеки собственных методов: набор собственных библиотек C / C ++, к которым можно получить доступ через предоставленный собственный интерфейс.

Типы данных JVM

JVM выполняет вычисления с определенными данными, поэтому типы данных и операции строго определены спецификацией виртуальной машины Java. На рисунке 4. показана классификация типов данных JVM.

В основном типы данных JVM можно разделить на два набора: примитивные и ссылочные типы данных. В примитивных типах данных они сами содержат фактические значения. Но в ссылочных типах данных держите ссылку на объект этого типа данных. При рассмотрении логического типа данных ложно представляет использование нуля и действительно представляет ненулевое значение с целочисленным типом данных. Но массив логических символов представлен одним байтом. Тип ReturnAddress недоступен для Java-программиста, и этот примитивный тип данных используется для реализации finally предложений программ Java. При рассмотрении ссылочного типа тип ссылки на класс содержит ссылку на объект класса, расположенный внутри области кучи. Ссылка на интерфейс содержит ссылку на объект некоторого класса, который реализует конкретный интерфейс, расположенный внутри области кучи, как тип данных класса.

Основной единицей размера значений данных в JVM является слово . Размер слова определяется разработчиками реализации JVM. Обычно слово должно удовлетворять следующим двум условиям.

  • слово должно содержать любой примитивный тип данных, указанный JVM.
  • Два слова должны поддерживать 64-битные двойные и длинные примитивные типы данных.

Исходя из этого, разработчики должны выбрать размер слова не менее 32-битного, чтобы хранить типы данных длиной 64-бит с двумя словами. Таблица 1. Иллюстрирует диапазоны типов данных в JVM.

Заключение

В соответствии с тем, что обсуждалось в вышеупомянутых темах, основная цель JVM - преобразовать байт-код в собственный код и выполнить его для получения вывода программы. В этой статье мы рассмотрели некоторые факты, связанные с архитектурой, компонентами и типами данных JVM.

Ссылки