Рубрики

Как работает JVM — Архитектура JVM?

JVM (виртуальная машина Java) действует как механизм времени выполнения для запуска приложений Java. JVM — это тот, который фактически вызывает метод main, присутствующий в коде Java. JVM является частью JRE (Java Runtime Environment).

Java-приложения называются WORA (Write Once Run Anywhere). Это означает, что программист может разрабатывать код Java в одной системе и ожидать, что он будет работать в любой другой системе с поддержкой Java без каких-либо настроек. Это все возможно благодаря JVM.

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

Подсистема загрузчика классов
В основном он отвечает за три вида деятельности.

  • загрузка
  • соединение
  • инициализация

Загрузка: Загрузчик классов читает файл .class , генерирует соответствующие двоичные данные и сохраняет их в области методов. Для каждого файла .class JVM хранит следующую информацию в области методов.

  • Полностью определенное имя загруженного класса и его непосредственного родительского класса.
  • Является ли файл .class связанным с Class или Interface или Enum
  • Информация о модификаторах, переменных и методах и т. Д.

После загрузки файла .class JVM создает объект типа Class для представления этого файла в памяти кучи. Обратите внимание, что этот объект имеет тип Class, предопределенный в пакете java.lang . Этот объект класса может использоваться программистом для получения информации уровня класса, такой как имя класса, имя родителя, методы и информация о переменной и т. Д. Чтобы получить эту ссылку на объект, мы можем использовать метод getClass () класса Object .

// Java-программа для демонстрации работы типа Class
// объект, созданный JVM для представления файла .class в
// Память.

import java.lang.reflect.Field;

import java.lang.reflect.Method;

  
// Java-код для демонстрации использования объекта Class
// созданный JVM

public class Test

{

    public static void main(String[] args)

    {

        Student s1 = new Student();

  

        // Получение объекта Class создано

        // от JVM.

        Class c1 = s1.getClass();

  

        // Печать типа объекта с использованием c1.

        System.out.println(c1.getName());

  

        // получение всех методов в массиве

        Method m[] = c1.getDeclaredMethods();

        for (Method method : m)

            System.out.println(method.getName());

  

        // получение всех полей в массиве

        Field f[] = c1.getDeclaredFields();

        for (Field field : f)

            System.out.println(field.getName());

    }

}

  
// Пример класса, информация которого извлекается выше с использованием
// его объект класса.

class Student

{

    private String name;

    private int roll_No;

  

    public String getName()  {  return name;   }

    public void setName(String name) { this.name = name; }

    public int getRoll_no()  { return roll_No;  }

    public void setRoll_no(int roll_no) {

        this.roll_No = roll_no;

    }

}

Выход:

Student
getName
setName
getRoll_no
setRoll_no
name
roll_No

Примечание. Для каждого загруженного файла .class создается только один объект класса.

Student s2 = new Student();
// c2 will point to same object where 
// c1 is pointing
Class c2 = s2.getClass();
System.out.println(c1==c2); // true

Связывание: выполняет проверку, подготовку и (необязательно) разрешение.

  • Проверка : обеспечивает правильность файла .class, т.е. проверяет, правильно ли отформатирован и сгенерирован ли этот файл корректным компилятором или нет. Если проверка не удалась, мы получаем исключение времени выполнения java.lang.VerifyError .
  • Подготовка : JVM выделяет память для переменных класса и инициализирует память значениями по умолчанию.
  • Решение . Это процесс замены символьных ссылок типа непосредственными ссылками. Это делается путем поиска в области метода, чтобы найти ссылку на объект.

Инициализация: на этом этапе всем статическим переменным присваиваются их значения, определенные в коде и статическом блоке (если есть). Это выполняется сверху вниз в классе и от родителя к потомку в иерархии классов.
В общем, есть три класса загрузчиков:

  • Загрузчик классов начальной загрузки. Каждая реализация JVM должна иметь загрузчик классов начальной загрузки, способный загружать доверенные классы. Он загружает основные классы API Java, представленные в каталоге JAVA_HOME / jre / lib . Этот путь обычно известен как путь начальной загрузки. Он реализован на родных языках, таких как C, C ++.
  • Загрузчик класса расширения : это дочерний элемент загрузчика класса начальной загрузки. Он загружает классы, представленные в каталогах расширений JAVA_HOME / jre / lib / ext (путь расширения) или в любом другом каталоге, указанном системным свойством java.ext.dirs. Он реализован в Java с помощью класса sun.misc.Launcher $ ExtClassLoader .
  • Загрузчик классов системы / приложения : это дочерний элемент загрузчика классов расширения. Он отвечает за загрузку классов из пути к классам приложения. Он внутренне использует переменную среды, которая сопоставлена с java.class.path. Он также реализован в Java классом sun.misc.Launcher $ AppClassLoader .

// Java-код для демонстрации подсистемы Class Loader

public class Test

{

    public static void main(String[] args)

    {

        // класс String загружается загрузчиком начальной загрузки и

        // загрузчик начальной загрузки не является объектом Java, следовательно, null

        System.out.println(String.class.getClassLoader());

  

        // Тестовый класс загружается загрузчиком приложений

        System.out.println(Test.class.getClassLoader());

    }

}    

Выход:

null
sun.misc.Launcher$AppClassLoader@73d16e93

Примечание: JVM следует принципу делегирования-иерархии для загрузки классов. Запрос на загрузку делегата загрузчика системного класса в загрузчик класса расширения и запрос делегата загрузчика класса расширения в загрузчик класса начальной загрузки. Если класс найден в пути начальной загрузки, класс загружается, в противном случае запрос снова передается загрузчику классов расширения, а затем системному загрузчику классов. Наконец, если загрузчик системного класса не может загрузить класс, мы получаем исключение java.lang.ClassNotFoundException во время выполнения .

Память JVM
Область метода: В области метода хранится вся информация уровня класса, такая как имя класса, имя непосредственного родительского класса, информация о методах и переменных и т. Д., Включая статические переменные. В JVM есть только одна область методов, и это общий ресурс.

Область кучи: информация обо всех объектах хранится в области кучи. Существует также одна область кучи на JVM. Это также общий ресурс.

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

Регистры ПК: Хранить адрес текущей инструкции исполнения потока. Очевидно, что каждый поток имеет отдельные регистры ПК.

Стеки собственного метода: для каждого потока создается отдельный собственный стек. Он хранит информацию о родном методе.

Двигатель исполнения
Механизм выполнения выполняет .class (байт-код). Он читает байт-код построчно, использует данные и информацию, присутствующую в различных областях памяти, и выполняет инструкции. Его можно разделить на три части:

  • Интерпретатор : Он интерпретирует байт-код построчно, а затем выполняет. Недостатком здесь является то, что когда один метод вызывается несколько раз, требуется интерпретация каждый раз.
  • Компилятор Just-In-Time (JIT) : используется для повышения эффективности интерпретатора. Он компилирует весь байт-код и заменяет его на собственный код, поэтому всякий раз, когда интерпретатор видит повторяющиеся вызовы методов, JIT предоставляет прямой собственный код для этой части, поэтому повторная интерпретация не требуется, таким образом, эффективность повышается.
  • Сборщик мусора : уничтожает не связанные объекты. Для получения дополнительной информации о сборщике мусора см. Сборщик мусора .

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

Библиотеки нативных методов:
Это коллекция родных библиотек (C, C ++), которые требуются для механизма выполнения.

Эта статья предоставлена Гауравом Миглани . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

Рекомендуемые посты:

Как работает JVM — Архитектура JVM?

0.00 (0%) 0 votes