Узнайте о различиях между JDK, JRE и JVM. Как JVM работает внутри? Что такое загрузчики классов, интерпретаторы и JIT-компиляторы? Также ознакомьтесь с некоторыми вопросами для собеседования по Java.
1. Поток выполнения программы Java
Прежде чем углубляться во внутреннее устройство Java, давайте разберемся, как выполняется исходный файл Java.
- Мы пишем исходный код Java в файле Simple.Java с помощью редактора или IDE(интегрированной среды разработки), например Eclipse или IntelliJ Idea.
- Программа должна быть скомпилирована в байт-код. Компилятор Java(javac) компилирует исходный код в файл Simple.class.
- Этот файл класса может быть выполнен на любой платформе/ОС с помощью JVM(виртуальной машины Java).
- JVM транслирует байт-код в машинный код, который могут выполнять машины.

2. Что такое JVM?
Виртуальная машина Java(JVM) — это виртуальная машина, которая запускает байт-коды Java. Вы получаете этот байт-код, компилируя файлы .java в файлы .class. Файлы .class содержат байт-коды, понятные JVM.
В реальном мире JVM — это спецификация, которая предоставляет среду выполнения, в которой может выполняться байт-код Java. Разные поставщики предоставляют разные реализации этой спецификации. Например, на этой странице вики перечислены разные реализации JVM.
Самой популярной реализацией JVM является Hotspot, которая принадлежит и предоставляется корпорацией Oracle(ранее Sun Microsystems, Inc.).
JVM обеспечивает оптимальную производительность для приложений Java, используя множество передовых технологий, включая современную модель памяти, сборщик мусора и адаптивный оптимизатор.
JVM поставляется в двух различных вариантах — клиент и сервер. Хотя серверная и клиентская виртуальные машины похожи, серверная виртуальная машина была специально настроена для максимизации пиковой скорости работы. Она предназначена для выполнения долго работающих серверных приложений, которым нужна максимально возможная скорость работы, а не быстрое время запуска или меньший объем памяти во время выполнения. Разработчики могут выбрать нужную им систему, указав -client или -server.
JVM называется виртуальной, потому что она обеспечивает машинный интерфейс, который не зависит от базовой операционной системы и аппаратной архитектуры машины. Эта независимость от оборудования и операционной системы является краеугольным камнем ценности написания-один раз-запуска-везде программ Java.
2.1 Архитектура JVM

2.1.1 Загрузчик классов
Загрузчик классов — это подсистема, используемая для загрузки файлов классов. Он выполняет три основные функции: загрузку классов, связывание и инициализацию.
Загрузка
- Для загрузки классов в JVM есть 3 вида загрузчиков классов: Bootstrap, Extension и Application Class Loader.
- При загрузке файла класса JVM обнаруживает зависимость для некоторого произвольного класса XYZ.class.
- Первый загрузчик классов bootstrap пытается найти класс. Он сканирует файл rt.jar в папке JRE lib.
- Если класс не найден, то загрузчик классов расширения ищет файл класса внутри папки jre\lib\ext.
- Опять же, если класс не найден, то загрузчик классов приложения ищет все Jar-файлы и классы в переменной среды CLASSPATH системы.
- Если класс найден каким-либо загрузчиком, то класс загружается загрузчиком классов; в противном случае выдается исключение ClassNotFoundException.
Связывание
После загрузки класса загрузчиком классов выполняется связывание. Верификатор байт-кода проверит, является ли сгенерированный байт-код правильным или нет. Если проверка не пройдена, мы получим ошибку проверки. Он также выполняет распределение памяти статическим переменным и методам, найденным в классе.
Инициализация
Это заключительная фаза загрузки класса, здесь всем статическим переменным будут присвоены исходные значения, и статические блоки будут выполнены.
2.1.2 Области памяти JVM
Область памяти внутри JVM разделена на несколько частей для хранения определенных фрагментов данных приложения.
- Область методов хранит структуры классов, такие как метаданные, константный пул времени выполнения и код методов.
- Куча хранит все объекты, созданные во время выполнения приложения.
- Стеки хранят локальные переменные и промежуточные результаты. Все такие переменные являются локальными для потока, которым они созданы. Каждый поток имеет свой собственный стек JVM, создаваемый одновременно с созданием потока. Поэтому все такие локальные переменные называются локальными переменными потока.
- Регистр PC хранит физический адрес памяти операторов, которые в данный момент выполняются. В Java каждый поток имеет свой отдельный регистр PC.
- Java также поддерживает и использует собственный код. Многие низкоуровневые коды написаны на таких языках, как C и C++. Стеки собственных методов содержат инструкции собственного кода.
2.2. Механизм выполнения JVM
Весь код, назначенный JVM, выполняется механизмом выполнения. Механизм выполнения считывает байт-код и выполняет его один за другим. Он использует два встроенных интерпретатора и JIT-компилятор для преобразования байт-кода в машинный код и его выполнения.

С JVM и интерпретатор, и компилятор производят собственный код. Разница в том, как они генерируют собственный код, насколько он оптимизирован, а также насколько затратна оптимизация.
2.2.1.Переводчик
Интерпретатор JVM в значительной степени преобразует каждую инструкцию байт-кода в соответствующую собственную инструкцию, просматривая предопределенную инструкцию JVM в сопоставление машинных инструкций. Он напрямую выполняет байт-код и не выполняет никакой оптимизации.
2.2.2 JIT-компилятор
Для повышения производительности JIT-компиляторы взаимодействуют с JVM во время выполнения и компилируют соответствующие последовательности байт-кода в машинный код. Обычно JIT-компилятор берет блок кода(а не один оператор за раз, как интерпретатор), оптимизирует код, а затем транслирует его в оптимизированный машинный код.
Компилятор JIT включен по умолчанию. Вы можете отключить компилятор JIT, в этом случае будет интерпретирована вся программа Java. Отключение компилятора JIT не рекомендуется, за исключением случаев диагностики или обхода проблем компиляции JIT.
3. Что такое JRE?
Java Runtime Environment(JRE) — это программный пакет, который объединяет библиотеки(jar) и виртуальную машину Java, а также другие компоненты для запуска приложений, написанных на Java. JVM — это всего лишь часть дистрибутивов JRE.
Для запуска любого приложения Java вам необходимо установить JRE на машине. Это минимальное требование для запуска приложений Java на любом компьютере.
JRE объединяет следующие компоненты:
- Файлы DLL, используемые виртуальной машиной клиента Java HotSpot.
- Файлы DLL, используемые виртуальной машиной Java HotSpot Server.
- Библиотеки кода, настройки свойств и файлы ресурсов, используемые средой выполнения Java, например, rt.jar и charsets.jar.
- Файлы расширения Java, такие как localedata.jar.
- Содержит файлы, используемые для управления безопасностью. К ним относятся файлы политики безопасности(java.policy) и свойств безопасности(java.security).
- Jar-файлы, содержащие классы поддержки для апплетов.
- Содержит файлы шрифтов TrueType для использования платформой.
JRE можно загрузить как часть JDK или отдельно. JRE зависят от платформы. Это означает, что в зависимости от типа машины(ОС и архитектура) вам придется выбрать пакет JRE для импорта и установки.
Например, вы не можете установить 64-битный дистрибутив JRE на 32-битную машину. Аналогично, дистрибутив JRE для Windows не будет работать в Linux; и наоборот.
4. Что такое JDK?
JDK — это надмножество JRE. JDK содержит все, что есть в JRE, а также инструменты разработки для разработки, отладки и мониторинга приложений Java. Вам нужен JDK, когда вам нужно разрабатывать приложения Java.
Вот несколько важных компонентов, поставляемых с JDK:
- appletviewer – этот инструмент можно использовать для запуска и отладки Java-апплетов без веб-браузера.
- apt – инструмент обработки аннотаций
- extcheck – утилита, обнаруживающая конфликты JAR-файлов
- javadoc – генератор документации, который автоматически создает документацию из комментариев исходного кода
- jar – архиватор, который упаковывает связанные библиотеки классов в один файл JAR. Этот инструмент также помогает управлять файлами JAR
- jarsigner – инструмент для подписи и проверки jar-файлов
- javap – дизассемблер файлов классов
- javaws – средство запуска Java Web Start для приложений JNLP
- JConsole – консоль мониторинга и управления Java
- jhat — инструмент анализа кучи Java
- jrunscript – оболочка скрипта командной строки Java
- jstack – утилита, которая печатает трассировки стека Java потоков Java
- keytool – инструмент для работы с хранилищем ключей
- policytool – инструмент создания и управления политикой
- xjc – Часть API Java API для XML Binding(JAXB). Принимает схему XML и генерирует классы Java
Как и JRE, JDK также зависят от платформы. Поэтому будьте осторожны, когда загружаете пакет JDK для своей машины.
5. Разница между JDK, JRE и JVM
На основании вышеизложенных рассуждений мы можем установить взаимосвязь между этими тремя факторами следующим образом:
JRE = JVM + библиотеки для запуска приложений Java.
JDK = JRE + инструменты для разработки Java-приложений.

Короче говоря, если вы разработчик приложений Java, который пишет код, вам понадобится JDK, установленный на вашем компьютере. Но если вы хотите запускать только приложения, созданные на Java, вам понадобится только JRE, установленный на вашем компьютере.
6. Вопросы интервью, связанные с JDK, JRE и JVM
Если вы поняли все, что мы обсуждали в этом посте, то ответить на любой вопрос на собеседовании не составит труда. Тем не менее, будьте готовы ответить на вопросы, подобные приведенным ниже:
Что такое архитектура JVM?
Это уже подробно объяснено.
Сколько типов загрузчиков классов существует в Java?
Существует 3 загрузчика классов: загрузчик начальной загрузки, загрузчик расширений и загрузчик классов приложений.
Как работает загрузчик классов в Java?
Загрузчики классов сканируют свои предопределенные расположения на предмет файлов jar и классов. Они сканируют все эти файлы классов в пути и ищут требуемый класс. Если он найден, они загружают, связывают и инициализируют файл класса.
В чем разница между JRE и JVM?
JVM — это спецификация для среды выполнения, которая выполняет приложения Java. Hotspot JVM — это одна из реализаций спецификации. Она загружает файлы классов и использует интерпретатор и JIT-компилятор для преобразования байт-кода в машинный код и его выполнения.
В чем разница между интерпретатором и JIT-компилятором?
Интерпретатор интерпретирует байт-код построчно и выполняет его последовательно. Это приводит к низкой производительности. JIT-компилятор добавляет оптимизацию к этому процессу, анализируя код по блокам, а затем подготавливает более оптимизированный машинный код.
7. Загрузка JDK и JRE
Программные пакеты JDK и JRE для конкретных платформ можно найти на страницах дистрибутивов Java компании Oracle.
Например, на этой странице перечислены все доступные дистрибутивы JDK для Java 8.

Аналогично, дистрибутивы JRE 8 доступны на этой странице.
