Ответ
JVM (Java Virtual Machine) разделяет память на несколько областей, каждая из которых имеет строго определенное назначение в жизненном цикле программы.
Основные области памяти JVM:
-
Heap (Куча):
- Назначение: Хранение всех объектов (экземпляров классов) и массивов, созданных во время выполнения программы (оператор
new). - Особенности: Общая для всех потоков. Управляется Сборщиком Мусора (Garbage Collector, GC). Разделяется на поколения (Young, Old) для оптимизации GC.
- Назначение: Хранение всех объектов (экземпляров классов) и массивов, созданных во время выполнения программы (оператор
-
Stack (Стек):
- Назначение: Хранение локальных переменных (примитивных типов и ссылок на объекты в куче), вызовов методов и частичных результатов. Создается отдельно для каждого потока.
- Особенности: Быстрый доступ (LIFO), ограниченный размер. Переполнение приводит к
StackOverflowError. Каждый вызов метода создает новый кадр стека (stack frame).
-
Method Area (Область Методов / Metaspace):
- Назначение: Хранение метаданных классов: структура класса, байт-код методов, статические переменные (
static), константы пула строк (String Pool), информация для рефлексии. - Особенности: В современных JVM (Java 8+) называется Metaspace и, как правило, выделяется из native-памяти (не из Heap).
- Назначение: Хранение метаданных классов: структура класса, байт-код методов, статические переменные (
-
Program Counter (PC) Register (Регистр Счетчика Команд):
- Назначение: Хранение адреса текущей выполняемой инструкции JVM для каждого потока. Если выполняется native-метод, значение не определено.
-
Native Method Stack:
- Назначение: Поддержка вызовов нативных методов (написанных на C/C++ через JNI). Создается для каждого потока.
Пример распределения:
public class MemoryExample {
private static int staticVar = 100; // Method Area (Metaspace)
private int instanceVar; // Heap (в составе объекта)
public void calculate(int param) { // Байт-код метода — Method Area
int localVar = param * 2; // Stack (в кадре метода calculate)
Object obj = new Object(); // Ссылка 'obj' — в Stack, сам Object — в Heap
System.out.println(localVar);
}
}