В чем разница между JVM, JRE и JDK
Что проверяют
Базовый вопрос: понимаете ли вы, что именно исполняет ваш код и что вы ставите на сервер. Следом обычно спрашивают, как JVM исполняет байт-код (интерпретатор и JIT) или что сейчас кладут в Docker-образ, если отдельной JRE от Oracle давно нет.
Как отвечать
Удобно идти изнутри наружу, это три вложенных уровня:
- JVM: виртуальная машина, которая загружает классы, проверяет байт-код и исполняет его. Сначала интерпретирует, а горячие методы компилирует в машинный код JIT-компилятором (в HotSpot это C1 и C2). Здесь же живут сборщик мусора, модель памяти и потоки. JVM это спецификация, реализаций несколько: HotSpot, OpenJ9, GraalVM;
- JRE: JVM плюс стандартная библиотека классов (
java.baseи остальные модули), то есть всё, что нужно для запуска готового приложения. Компилятора в ней нет; - JDK: JRE плюс инструменты разработчика:
javac,jar,jdb,javadoc,jshell,jlink,jcmd,jfr.
Платформонезависимость держится на связке: javac один раз компилирует исходник в байт-код, а под каждую ОС и архитектуру есть своя JVM.
Хорошо добавить современный контекст. Начиная с Java 11 Oracle не выпускает JRE отдельным дистрибутивом, ставится JDK. Некоторые сборки OpenJDK, например Eclipse Temurin, по-прежнему публикуют JRE, но в продакшене часто делают иначе: собирают через jlink урезанный рантайм только с теми модулями, которые нужны приложению, и кладут его в образ. Образ получается заметно меньше.
Где спотыкаются
Говорят, что JVM «интерпретирует байт-код», и на этом останавливаются. Без JIT непонятно, почему Java-приложению нужен прогрев и почему первые запросы медленнее остальных.
Путают вложенность: считают, что в JRE есть компилятор, или что JDK и JRE это альтернативы, а не одно внутри другого.
Называют платформонезависимой всю Java и забывают, что сама JVM как раз платформозависима: это нативная программа, собранная под конкретную ОС и процессор.