Как устроена структура памяти JVM?

«Как устроена структура памяти JVM?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Память в JVM разделена на несколько основных областей, каждая из которых отвечает за хранение определённых данных и имеет свой жизненный цикл.

Основные области памяти JVM:

  1. Heap (Куча) — самая большая область. Здесь создаются все объекты и массивы. Управляется сборщиком мусора (GC).

    • Young Generation: Куда помещаются новые объекты. Состоит из Eden и двух Survivor Spaces. Частые минорные сборки (Minor GC).
    • Old Generation (Tenured): Сюда перемещаются объекты, пережившие несколько циклов GC в Young Generation. Редкие мажорные сборки (Major/Full GC).
  2. Metaspace (с Java 8) — заменяет устаревшую PermGen. Хранит метаданные классов, информацию о загруженных классах, статические переменные, константы пула строк.

  3. JVM Stack (Стек) — создаётся для каждого потока. Хранит фреймы методов: локальные переменные (примитивы и ссылки), частичные результаты и данные для вызовов методов.

  4. Program Counter (PC) Register — для каждого потока хранит адрес текущей выполняемой инструкции JVM.

  5. Native Method Stack — обслуживает вызовы нативных методов (написанных на C/C++).

Наглядный пример распределения:

public class MemoryStructure {
    private static int staticVar = 100; // Metaspace (раньше PermGen)
    private int instanceVar;            // Heap (в составе объекта)

    public void method() {
        int localVar = 50;              // JVM Stack (во фрейме метода 'method')
        Object obj = new Object();      // Объект в Heap, ссылка 'obj' в Stack
    }
}