Ответ
Память в JVM разделена на несколько основных областей, каждая из которых отвечает за хранение определённых данных и имеет свой жизненный цикл.
Основные области памяти JVM:
-
Heap (Куча) — самая большая область. Здесь создаются все объекты и массивы. Управляется сборщиком мусора (GC).
- Young Generation: Куда помещаются новые объекты. Состоит из Eden и двух Survivor Spaces. Частые минорные сборки (Minor GC).
- Old Generation (Tenured): Сюда перемещаются объекты, пережившие несколько циклов GC в Young Generation. Редкие мажорные сборки (Major/Full GC).
-
Metaspace (с Java 8) — заменяет устаревшую PermGen. Хранит метаданные классов, информацию о загруженных классах, статические переменные, константы пула строк.
-
JVM Stack (Стек) — создаётся для каждого потока. Хранит фреймы методов: локальные переменные (примитивы и ссылки), частичные результаты и данные для вызовов методов.
-
Program Counter (PC) Register — для каждого потока хранит адрес текущей выполняемой инструкции JVM.
-
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
}
} Ответ 18+ 🔞
А, слушай, ну вот опять про эту память в Java. Сидишь такой, пишешь код, а оно тебе — OutOfMemoryError, пиздец! А всё потому, что не понимаешь, куда что летит. Давай разберём, как эта штука устроена, чтоб потом не охуевать.
Вот представь, что JVM — это такой большой, блядь, склад. И на этом складе есть разные отделы, куда мусор свозят по-разному. Главный отдел, самый забитый — это Heap (Куча). Туда, сука, попадает вообще всё, что ты создаёшь через new. Все твои объекты, массивы — всё там, в этой куче. А внутри этой кучи ещё деление есть, хитрая жопа!
Сначала объекты попадают в Young Generation — это типа приёмный покой для новорождённых. Там есть Eden (Эдем, иронично, да? Потому что скоро оттуда всех выгонят) и два Survivor Space. Пока объект молодой и горячий, он там скачет из Эдема в сервайворы и обратно. А как постареет, переживёт несколько уборок — его отправляют на пенсию в Old Generation. Там уже пореже мусор вывозят, но зато основательно, всей командой.
А раньше была ещё PermGen, все её боялись. Теперь её заменили на Metaspace. Это, типа, архив. Туда складывают не объекты, а чертежи к ним — метаданные классов, всякие статические переменные, названия методов. Бесконечно расширяемый архив, в теории. На практике тоже можно его дохуя раздуть, если очень постараться.
Дальше идёт JVM Stack (Стек). Это, блядь, не куча, а индивидуальная тумбочка для каждого потока. Каждый раз, когда поток заходит в метод, ему выделяют ящичек в этой тумбочке — фрейм. Туда он кладёт свои локальные переменные (примитивы и ссылки на объекты из кучи, сами понимаете). Вышел из метода — ящичек выкинули. Красиво.
Program Counter Register — это такая бумажка-напоминалка для каждого потока. На ней написано: "на каком шаге инструкций я сейчас остановился". Чтоб не потеряться.
И Native Method Stack — это отдельная комната для гостей из другого мира, для нативных методов на C++. Туда мы обычно не лезем, если не хотим проблем.
Вот смотри, как это всё в коде выглядит, чтоб не быть просто болтовнёй:
public class MemoryStructure {
private static int staticVar = 100; // Это, блядь, летит прямиком в Metaspace. Не в кучу!
private int instanceVar; // А это — уже в Heap, внутри каждого созданного объекта.
public void method() {
int localVar = 50; // Эта циферка живёт уютно в стеке, во фрейме метода 'method'.
Object obj = new Object(); // Вот тут магия! Сам объект new Object() — в куче (Heap).
// А ссылка 'obj' на него — в стеке, в том же фрейме.
// Вышел из метода — ссылка 'obj' испарилась из стека.
// А объект в куче остался, пока его сборщик мусора не приберёт.
}
}
Вот и вся магия, ёпта. Понял, где что лежит — уже полдела в оптимизации и отладке сделал. А то будешь как Герасим — "Мууу!" говорить, когда память кончится, и нихуя не понять, почему.