Runtime data areas (области памяти)
JVM делит память на несколько областей. Две главные — Stack и Heap:
Stack — каждый поток имеет свой стек. Хранит фреймы вызовов: локальные переменные и примитивы. Автоматически очищается при выходе из метода. StackOverflowError — стек переполнен (бесконечная рекурсия).
Heap — общая для всех потоков. Хранит объекты. Управляется GC. OutOfMemoryError: Java heap space — куча переполнена.
Ключевое правило: примитивы в методах — на стеке, объекты — всегда на куче (на стеке хранится только ссылка на объект).
void method() {
int x = 5; // на стеке
String s = "hello"; // ссылка на стеке, объект String — в куче
User u = new User(); // ссылка на стеке, объект User — в куче
}
Копнуть глубже
Полный список областей памяти JVM:
| Область | Что хранит | На поток? |
|---|---|---|
| Stack | фреймы вызовов, локальные переменные, примитивы | ✅ свой у каждого |
| Heap | объекты, массивы | ❌ общая |
| Metaspace | метаданные классов (с Java 8, замена PermGen) | ❌ общая |
| PC Register | текущая инструкция байт-кода | ✅ свой у каждого |
| Native Stack | фреймы нативных методов (JNI) | ✅ свой у каждого |
Escape Analysis — оптимизация JIT-компилятора: если объект не «убегает» за пределы метода, JVM может размесить его на стеке (быстрее) вместо кучи:
void compute() {
Point p = new Point(1, 2); // p не передаётся никуда → может быть на стеке
return p.x + p.y;
}
-Xss, -Xmx, -Xms — настройка памяти:
-Xmx4g # максимум кучи 4 GB
-Xms4g # начальный размер (= max → без resize, лучше для продакшна)
-Xss512k # размер стека на поток (дефолт 512KB-1MB)
🎤 Закрыл тему, если можешь объяснить:
• разницу Stack и Heap: что где хранится, для кого общее, для кого личное;
• что такое Metaspace и чем отличается от PermGen, как настроить размер кучи (если дошёл до 2-го слоя).
• что такое Metaspace и чем отличается от PermGen, как настроить размер кучи (если дошёл до 2-го слоя).