Новый перевод от команды Spring АйО расскажет вам, что происходит при запуске самого простого приложения на Java, какие шаги выполняет JVM, сколько классов ей необходимо загрузить, чтобы просто написать “Hello World!” и как все это выглядит на уровне byte code.
Когда вы запускаете приложение на Java, может возникать тенденция поверить в то, что единственный выполняемый в этот момент код — это Java byte code, передаваемый JVM, то есть файлы .class, откомпилированные javac. На самом деле во время запуска приложения JVM проходит через сложную последовательность шагов, создавая своего рода маленькую вселенную, в которой приложение будет работать. В этой статье мы посмотрим на все шаги, через которые JVM проходит между $ java и выводом строки Hello World. Если вы предпочитаете видео формат, есть также видео на YouTube на канале Java, где рассказывается все то же самое (но на английском — прим. пер.).
Введение
Чтобы этот обзор процедуры запуска не превратился в попытку “вскипятить океан”, мы добавим кое-какие ограничения, которые я буду использовать при описании процесса:
Я буду описывать процедуру запуска JVM, как она происходит в JDK 23. Спецификацию JVM для Java SE 23 можно посмотреть здесь.
Я буду использовать реализацию HotSpot JVM в качестве примера. Это наиболее часто используемая реализация JVM, многие популярные дистрибутивы JDK используют HotSpot JVM или ее производные. Альтернативные реализации JVM могут слегка отличаться внутренним поведением.
Ну и наконец, главным примером кода, используемым для описания процедуры старта JVM, будет
HelloWorld, поскольку это приложение, хоть и является самым простым на свете, все еще включает все ключевые части процедуры запуска JVM.
Несмотря на эти ограничения, после прочтения этой статьи у вас появится довольно полное представление о процессах, через которые проходит JVM при запуске, как и о том, для чего они нужны. Это знание поможет вам при отладке приложения, если при его старте появятся проблемы, а в некоторых особых случаях будет полезно и для улучшения производительности. Хотя об этом мы поговорим ближе к концу статьи.
Инициализация JVM
Когда пользователь вводит команду java, начинается процедура старта JVM, при этом вызывается функция JNI (Java Native Interface), JNI_CreateJavaVM(), код этой функции вы можете просмотреть здесь. Эта функция JNI сама по себе выполняет несколько важных процессов.
Валидация ввода пользователя
Первый шаг в процедуре старта JVM — это валидация введенных пользователем данных: JVM аргументы, артефакт для выполнения и classpath. Ниже приведен фрагмент лога, который показывает, как происходит валидация:
[arguments] VM Arguments:
[arguments] jvm_args: -Xlog:all=trace
[arguments] java_command: HelloWorld
[arguments] java_class_path (initial): .
[arguments] Launcher Type: SUN_STANDARD
