← Назад к вопросам

В какой формат JVM компилирует код

1.3 Junior🔥 131 комментариев
#JVM и управление памятью#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В какой формат JVM компилирует код

Java компилируется в байт-код (bytecode), который затем интерпретируется и компилируется JVM во время выполнения (JIT compilation).

1. Java Source Code → Bytecode

Исходный код Java компилируется в byte-код с помощью javac:

# Исходный файл
$ cat Hello.java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

# Компиляция
$ javac Hello.java

# Результат - файл .class
$ ls -la Hello.class

2. Формат Bytecode (.class файлы)

Байт-код - это промежуточный формат, независимый от платформы. Структура .class файла:

[Magic Number: 0xCAFEBABE]
[Minor Version]
[Major Version]
[Constant Pool]
[Class Flags]
[This Class]
[Super Class]
[Interfaces]
[Fields]
[Methods]
[Attributes]

3. Как выглядит байт-код

Можно посмотреть с помощью javap (Java disassembler):

$ javap -c Hello.class

Public class Hello {
  public Hello();
    Code:
       0: aload_0
       1: invokespecial #1  // Method java/lang/Object.<init>()
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2  // Field java/lang/System.out
       3: ldc           #3  // String Hello, World!
       5: invokevirtual #4  // Method java/io/PrintStream.println()
       8: return
}

Каждая инструкция - это одна операция, которую понимает JVM.

4. JVM интерпретирует или компилирует bytecode

Kogda JVM загружает .class файл, она выполняет код одним из двух способов:

Интерпретация (Interpretation)

  • JVM читает bytecode инструкцию за инструкцией
  • Преобразует в машинный код и выполняет
  • Медленнее, но не требует времени на компиляцию

JIT компиляция (Just-In-Time Compilation)

  • Если метод вызывается часто, JIT компилятор преобразует bytecode в машинный код процессора
  • Машинный код хранится в памяти
  • При следующих вызовах код выполняется очень быстро
public class PerformanceDemo {
    public static void main(String[] args) {
        // Первые несколько вызовов - интерпретация
        for (int i = 0; i < 10000; i++) {
            sum(1, 2);
        }
        // Метод был вызван много раз, JIT скомпилирует его
        // Следующие вызовы будут в машинном коде
    }
    
    static int sum(int a, int b) {
        return a + b; // JIT оптимизирует это
    }
}

5. Байт-код как платформа-независимость

За счёт bytecode достигается "Write Once, Run Anywhere" (WORA):

Java Source Code (Hello.java)
        ↓
    javac
        ↓
Platform-independent Bytecode (Hello.class) ← один файл!
        ↓
   ┌────┴────┐
   ↓         ↓
JVM на    JVM на
Linux     Windows
   ↓         ↓
Machine Code (x86)  Machine Code (x86)

Один .class файл работает везде, где установлена JVM.

6. Версии bytecode

Версия bytecode указана в Major Version поля .class файла:

$ javap -v Hello.class | grep version
  minor version: 0
  major version: 61  # Java 17

# Маппинг версий:
# 61 = Java 17
# 52 = Java 8
# 55 = Java 11
# 56 = Java 12

7. Инструкции bytecode

ВСЕ операции bytecode - это простые инструкции:

// Java код
int x = 10;
int y = 20;
int z = x + y;

// Bytecode (упрощённо)
LDC 10        // загрузить константу 10 в стек
ISTORE 1      // сохранить в переменную x (индекс 1)
LDC 20        // загрузить константу 20
ISTORE 2      // сохранить в переменную y
ILOAD 1       // загрузить x из памяти
ILOAD 2       // загрузить y
IADD          // сложить два верхних значения стека
ISTORE 3      // сохранить результат в z

8. Несколько языков на JVM

Ключевое преимущество bytecode - что на JVM могут работать другие языки, которые компилируются в тот же bytecode:

Java Code  →  Bytecode  ←  Kotlin Code
              ↓
         JVM Bytecode
              ↓
         Machine Code
  • Java → bytecode (javac)
  • Kotlin → bytecode (kotlinc)
  • Scala → bytecode (scalac)
  • Groovy → bytecode (groovyc)

Все эти языки работают на одной JVM.

9. Пример полного процесса

# Шаг 1: Написать код
$ cat Calculator.java
public class Calculator {
    public int multiply(int a, int b) {
        return a * b;
    }
}

# Шаг 2: Скомпилировать в bytecode
$ javac Calculator.java

# Шаг 3: Выполнить bytecode на JVM
$ java Calculator

# JVM выполнит:
# 1. Прочитает bytecode из Calculator.class
# 2. Проверит его (verification)
# 3. Загрузит классы (loading)
# 4. Свяжет (linking)
# 5. Выполнит (execution)

Вывод

JVM компилирует Java код в bytecode - независимый от платформы промежуточный формат. Bytecode хранится в .class файлах и содержит инструкции, которые JVM понимает. При выполнении JVM интерпретирует bytecode или компилирует его в машинный код с помощью JIT компилятора. Это обеспечивает портативность Java программ и возможность работы различных языков на одной платформе.