Перейти к содержанию

Разница между JVM, JRE и JDK

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

JVM

Java Virtual Machine (JVM) – это реализация виртуальной машины, которая выполняет программу Java.

JVM сначала интерпретирует байт-код. Затем сохраняет информацию о классе в области памяти. Наконец, выполняет байт-код, сгенерированный компилятором Java.

Это абстрактная вычислительная машина с собственным набором инструкций, которая манипулирует различными областями памяти во время выполнения.

Компоненты JVM:

  • загрузчики классов (Class Loaders);
  • области данных времени выполнения (Run-Time Data Areas);
  • механизм выполнения (Execution Engine).

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

Начальные задачи JVM включают загрузку, проверку и связывание байт-кода. Загрузчики классов справляются с этими задачами.

Есть подробная статья специально о загрузчиках классов.

Области данных времени выполнения

JVM определяет различные области памяти для выполнения программы Java. Они используются во время выполнения и известны как Run-Time Data Areas. Некоторые из этих областей создаются при запуске JVM и уничтожаются при выходе из JVM, а некоторые создаются при создании потока и уничтожаются при выходе из него.

Рассмотрим эти области по порядку:

Область метода

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

JVM хранит эту структуру для каждого класса.

Область метода, также известная как постоянное пространство генерации (PermGen), создается при запуске JVM. Память для этой области не обязательно должна быть непрерывной. Все потоки JVM совместно используют эту область памяти.

Область кучи (heap)

JVM выделяет память для всех экземпляров классов и массивов из этой области.

Сборщик мусора (GC) освобождает память кучи для объектов. По сути, у GC есть три фазы для освобождения памяти от объектов: две второстепенные (minor GC) и одна основная (major GC).

Куча состоит из трех частей:

  1. Eden Space – это часть пространства Young Generation. Когда мы создаем объект, JVM выделяет память из этого пространства.
  2. Survivor Space – это тоже часть пространства Young Generation. Пространство выживших содержит существующие объекты, которые пережили второстепенные фазы GC.
  3. Tenured Space — известное как пространство старого поколения. В нем хранятся долгоживущие объекты. По сути, для объектов Young Generation устанавливается пороговое значение, и при достижении этого порога эти объекты перемещаются в постоянное пространство (Tenured Space).

JVM создает область кучи сразу после запуска. Все потоки JVM совместно используют эту область. Память для кучи не обязательно должна быть непрерывной.

Область стека (stack)

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

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

  1. Local Variable Array (массив локальных переменных) – содержит все локальные переменные и параметры метода.
  2. Operand Stack (стек операндов) – используется как рабочая область для хранения результатов промежуточных вычислений.
  3. Frame Data (данные фрейма) – используются для хранения частичных результатов, возвращаемых значений для методов и ссылки на таблицу исключений, которая предоставляет соответствующую информацию о блоке перехвата в случае исключений.

Память для стека JVM не обязательно должна быть непрерывной.

Регистры ПК

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

Стеки нативных методов

Нативные методы написаны на языках, отличных от Java.

JVM предоставляет возможности для вызова нативных методов. Стеки нативных методов также известны как “C stacks”. Они хранят информацию о нативном методе. Всякий раз, когда нативные методы компилируются в машинные коды, они обычно используют стек нативных методов для отслеживания своего состояния.

JVM создает эти стеки всякий раз, когда создает новый поток. Таким образом, потоки JVM не разделяют эту область.

Механизм выполнения (Execution Engine)

Execution Engine выполняет инструкции, используя информацию, присутствующую в областях памяти. Он состоит из трех частей:

Интерпретатор (Interpreter)

Как только загрузчики классов загружают и проверяют байт-код, интерпретатор выполняет байт-код построчно. Это выполнение довольно медленное. Недостатком интерпретатора является то, что при многократном вызове одного метода каждый раз требуется новая интерпретация.

Однако JVM использует компилятор JIT, чтобы смягчить этот недостаток.

Компилятор Just-In-Time (JIT)

JIT компилирует байт-код часто вызываемых методов в собственный код во время выполнения. Следовательно, он отвечает за оптимизацию программ Java.

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

В результате он не прерывает выполнение текущей программы. После компиляции в машинный код он работает быстрее.

Сборщик мусора (Garbage Collector)

Java заботится об управлении памятью с помощью сборщика мусора. Это процесс просмотра динамической памяти, определения того, какие объекты используются, а какие нет, и, наконец, удаления неиспользуемых объектов.

GC – это поток демона. Его можно вызвать явно с помощью метода System.gc(), однако он не будет выполнен немедленно. JVM решает, когда вызывать сборщик мусора.

Нативный интерфейс Java

Он действует как интерфейс между кодом Java и нативными библиотеками (C/C++).

Бывают ситуации, когда Java сама по себе не отвечает потребностям приложения, например, при реализации функции, зависящей от платформы.

В этих случаях можно использовать JNI, чтобы запустить код в JVM. И наоборот, он позволяет нативным методам вызывать код, работающий в JVM.

Нативные библиотеки

Это специфичные для платформы библиотеки, содержащие реализацию нативных методов.

JRE

Java Runtime Environment (JRE) – это набор программных компонентов, используемых для запуска приложений Java.

Основные компоненты JRE включают:

  • реализация виртуальной машины Java (JVM);
  • классы, необходимые для запуска программ Java;
  • файлы свойств.

Мы обсудили JVM в предыдущем разделе. Здесь сосредоточимся на основных классах и файлах поддержки.

Классы начальной загрузки (Bootstrap Classes)

Классы начальной загрузки находятся в jre/lib/. Этот путь также известен как bootstrap classpath. Он включает в себя:

  • классы времени выполнения в rt.jar;
  • классы интернационализации в i18n.jar;
  • классы преобразования символов в charsets.jar;
  • прочее.

Bootstrap ClassLoader загружает эти классы при запуске JVM.

Классы расширений (Extension Classes)

Классы расширений находятся в jre/lib/extn/, который действует как каталог для расширений для платформы Java. Этот путь также известен как extension classpath.

Он содержит библиотеки времени выполнения JavaFX в файле jfxrt.jar и данные локали для пакетов java.text и java.util в файле localedata.jar. Пользователи также могут добавлять собственные файлы *.jar в этот каталог.

Настройки свойства (Property Settings)

Платформа Java использует настройки свойств для поддержания своей конфигурации. В зависимости от их использования они находятся в разных папках внутри /jre/lib/. Они включают:

  • конфигурации календаря в calendar.properties;
  • конфигурации логирования в logging.properties;
  • сетевые конфигурации в net.properties;
  • свойства развертывания в /jre/lib/deploy/;
  • свойства управления в /jre/lib/management/.

Прочие файлы

Помимо вышеупомянутых файлов и классов, JRE также содержит файлы для других целей:

  • управление безопасностью в jre/lib/security;
  • каталог для размещения классов поддержки апплетов в jre/lib/applet;
  • файлы, связанные со шрифтами, в jre/lib/fonts и др.

JDK

Java Development Kit (JDK) предоставляет среду и инструменты для разработки, компиляции, отладки и выполнения программы Java.

Основные компоненты JDK включают в себя:

  • JRE;
  • инструменты разработки.

Мы обсуждали JRE в предыдущем разделе.

Теперь сосредоточимся на различных инструментах разработки. Давайте классифицируем эти инструменты в зависимости от их использования:

Основные инструменты

Эти инструменты составляют основу JDK и используются для создания и сборки Java-приложений. Среди них можно найти утилиты для компиляции, отладки, архивирования, создания Javadocs и т. д.

Они включают:

  • javac – читает определения классов и интерфейсов и компилирует их в файлы классов;
  • java – запускает Java-приложение;
  • javadoc – генерирует HTML-страницы документации API из исходных файлов Java;
  • apt – находит и выполняет обработчики аннотаций на основе аннотаций, присутствующих в наборе указанных исходных файлов;
  • appletviewer – позволяет запускать апплеты Java без веб-браузера;
  • jar – упаковывает Java-апплеты или приложения в один архив;
  • jdb – инструмент отладки командной строки, используемый для поиска и исправления ошибок в приложениях Java;
  • javah – создает заголовочные и исходные файлы C из класса Java;
  • javap – дизассемблирует файлы классов и отображает информацию о полях, конструкторах и методах, присутствующих в файле класса;
  • extcheck – обнаруживает конфликты версий между целевым файлом Java Archive (JAR) и установленными в настоящее время JAR-файлами расширения.

Инструменты безопасности

К ним относятся инструменты управления ключами и сертификатами, которые используются для управления хранилищами ключей Java.

Хранилище ключей Java – это контейнер для сертификатов авторизации или сертификатов открытого ключа. Следовательно, он часто используется приложениями на основе Java для шифрования, аутентификации и обслуживания по протоколу HTTPS.

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

Они включают:

  • keytool – помогает в управлении записями хранилища ключей, а именно криптографическими ключами и сертификатами;
  • jarsigner – создает файлы JAR с цифровой подписью, используя информацию о хранилище ключей;
  • policytool – позволяет управлять файлами конфигурации внешней политики, которые определяют политику безопасности установки.

Некоторые инструменты безопасности также помогают управлять тикетами Kerberos.

Kerberos – это сетевой протокол аутентификации. Он работает на основе тикетов, позволяющих узлам, взаимодействующим по незащищенной сети, безопасно подтверждать свою личность друг другу:

  • kinit – используется для получения и кэширования тикетов на выдачу тикетов Kerberos;
  • ktab – управляет именами правил (principle) и парами ключей в таблице ключей;
  • klist – отображает записи в локальном кеше учетных данных и таблице ключей

Инструмент интернационализации

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

Для этой цели JDK предоставляет native2ascii. Этот инструмент преобразует файл с символами, поддерживаемыми JRE, в файлы, закодированные в escape-последовательности ASCII или Unicode.

Инструменты удаленного вызова методов (RMI)

Инструменты RMI обеспечивают удаленную связь между Java-приложениями, тем самым предоставляя возможности для разработки распределенных приложений.

RMI позволяет объекту, работающему на одной JVM, вызывать методы объекта, работающего на другой JVM. Эти инструменты включают в себя:

  • rmic – генерирует классы-заглушки, скелеты и связи для удаленных объектов с использованием протокола удаленных методов Java (JRMP) или протокола Internet Inter-Orb (IIOP);
  • rmiregistry – создает и запускает реестр удаленных объектов;
  • rmid – запускает демон системы активации, что позволяет регистрировать и активировать объекты в виртуальной машине Java;
  • serialver – возвращает UID серийной версии для указанных классов.

Инструменты Java IDL и RMI-IIOP

Язык определения интерфейса Java (IDL) добавляет к платформе Java возможность общей объектно-ориентированной архитектуры посредника запросов (CORBA).

Эти инструменты позволяют распределенным веб-приложениям Java вызывать операции с удаленными сетевыми службами с помощью стандартной группы управления объектами (OMG) – IDL.

Точно так же можно использовать интернет-протокол InterORB (IIOP).

RMI-IIOP, т. е. RMI поверх IIOP, позволяет программировать серверы и приложения CORBA через RMI API. Таким образом, обеспечивается связь между двумя приложениями, написанными на любом языке, совместимом с CORBA, через интернет-протокол InterORB (IIOP).

Эти инструменты включают в себя:

  • tnameserv – временная служба именования, которая предоставляет каталог с древовидной структурой для ссылок на объекты;
  • idlj – компилятор IDL-to-Java для создания привязок Java для указанного файла IDL;
  • orbd – позволяет клиентам прозрачно находить и вызывать постоянные объекты на сервере в среде CORBA;
  • servertool – предоставляет интерфейс командной строки для регистрации или отмены регистрации постоянного сервера с помощью ORB Daemon (orbd), запуска и выключения постоянного сервера, зарегистрированного с помощью ORB Daemon, и т. д.

Инструменты развертывания Java

Эти инструменты помогают развертывать Java-приложения и апплеты в интернете. Они включают:

  • pack200 – преобразует файл JAR в файл pack200 с помощью сжатия Java gzip;
  • unpack200 – преобразует файл pack200 в файл JAR.

Подключаемый модуль Java

JDK предоставляет htmlconverter. Кроме того, он используется вместе с подключаемым модулем Java.

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

С другой стороны, htmlconverter – это утилита для преобразования страницы HTML, содержащей апплеты, в формат для подключаемого модуля Java.

Инструмент веб-запуска Java

JDK предоставляет javaws. Можно использовать его вместе с Java Web Start.

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

Инструменты мониторинга и управления

Это отличные инструменты, которые можно использовать для мониторинга производительности JVM и потребления ресурсов. Вот некоторые из них:

  • jconsole – предоставляет графическую консоль, позволяющую отслеживать приложения Java и управлять ими;
  • jps – перечисляет инструментированные JVM в целевой системе;
  • jstat – отслеживает статистику JVM;
  • jstatd – отслеживает создание и завершение инструментированных JVM.

Инструменты устранения неполадок

Это экспериментальные инструменты, которые можно использовать для устранения неполадок:

  • info – генерирует информацию о конфигурации для указанного процесса Java;
  • jmap – печатает карты памяти общих объектов или сведения о памяти кучи указанного процесса;
  • jsadebugd – присоединяется к процессу Java и действует как сервер отладки;
  • jstack – выводит трассировку стека Java потоков Java для данного процесса Java.

Заключение

В этой статье определили, что основное различие между JVM, JRE и JDK заключается в их использовании.

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

Затем мы объяснили, как просто запускать Java-приложения, используя JRE.

И, наконец, мы поняли, как разрабатывать Java-приложения, используя JDK.

Мы также потратили некоторое время на изучение инструментов и фундаментальных концепций этих компонентов.

Оригинал