Что хранится в куче (Heap) памяти JVM?

Ответ

Куча (Heap) — это область памяти JVM, в которой хранятся все объекты и массивы, созданные во время выполнения Java-приложения. Управление памятью в куче осуществляется автоматически сборщиком мусора (Garbage Collector, GC).

Что именно хранится в Heap:

  • Экземпляры классов (объекты), созданные оператором new.
  • Массивы (включая массивы примитивов).
  • Строковый пул (String Pool) для интернированных строк (находится внутри Heap).
  • Поля объектов (как примитивные, так и ссылки на другие объекты).

Структура Heap (поколения):

  1. Young Generation – Для недолгоживущих объектов.
    • Eden – Сюда помещаются все новые объекты.
    • Survivor Spaces (S0, S1) – Сюда перемещаются объекты, пережившие Minor GC.
  2. Old Generation (Tenured) – Для долгоживущих объектов, переживших несколько сборок в Young Generation.
  3. Metaspace (вне Heap, но управляется JVM) – Для метаданных классов (с Java 8, заменила PermGen).

Пример:

// Объект MyClass и его внутренние данные — в Heap
MyClass obj = new MyClass();

// Массив и его элементы (примитивы) — в Heap
int[] numbers = new int[]{1, 2, 3};

// Строковый литерал — ссылка из пула строк (в Heap)
String name = "Java";

// Ссылка 'obj' хранится в стеке (Stack), а сам объект — в куче.

Ключевые моменты:

  • Heap общий для всех потоков приложения.
  • Память выделяется динамически.
  • Основная причина OutOfMemoryError: Java heap space — нехватка места в куче.

Ответ 18+ 🔞

Давай разберём эту кучу, блядь, по косточкам, чтобы мозг не взорвался от казёнщины. Представь, что куча — это такой общий склад, помойка, ёпта, куда всё сваливается, когда ты в своей программе начинаешь плодить объекты.

Куча (Heap) — это, грубо говоря, огромная общая свалка памяти внутри JVM, куда летят все объекты и массивы, которые ты наклепал оператором new. А самое главное — за порядком на этой свалке следит сборщик мусора (Garbage Collector, GC), который, как уборщик-алкаш, периодически приходит и выносит то, что уже никому не нужно. Автоматом, блядь!

Что валяется на этой свалке:

  • Все твои объекты, созданные через new MySuperPuperClass().
  • Все массивы, даже с примитивами внутри.
  • Строковый пул (String Pool) — специальная полочка для интернированных строк, которая тоже прикручена к этой куче.
  • Внутренности объектов — их поля, будь то примитивы или ссылки на другие объекты (которые, естественно, тоже на свалке).

Как эта свалка устроена (поколения, блядь):

  1. Young Generation (Молодёжь) – Для недолговечного шлака, который быстро появляется и быстро исчезает.
    • Eden (Эдем) – Сюда приземляются все свежесозданные объекты. Рай для новичков, ёпта.
    • Survivor Spaces (S0, S1, Выжившие) – Сюда переезжают те, кто пережил первую уборку (Minor GC). Как общага для стойких.
  2. Old Generation (Старики, Tenured) – Сюда попадают матёрые объекты, которые пережили несколько чисток в молодёжке. Живут долго, засиживаются.
  3. Metaspace (Мета-свалка, вне кучи, но своя) – Тут лежат метаданные классов (с Java 8). Раньше это была PermGen, но её, слава богу, убрали, потому что там вечно было тесно, пиздец.

Пример, чтобы вообще всё встало на свои места:

// Сам объект MyClass и всё, что внутри него — летит прямиком в кучу, на свалку.
MyClass obj = new MyClass();

// Массив numbers и его циферки 1, 2, 3 — тоже в куче, блядь.
int[] numbers = new int[]{1, 2, 3};

// Строка "Java" — если она литерал, то её ссылка тянется из того самого строкового пула, который ВНУТРИ кучи.
String name = "Java";

// А вот сама переменная-ссылка 'obj' — это просто бумажка с адресом. Она живёт в стеке (Stack). А реальный объект — там, на свалке.

Что важно уяснить, чтобы не облажаться:

  • Куча — одна на всё приложение, все потоки в ней роются.
  • Память там выделяется по мере надобности, динамически.
  • Если свалка переполняется и уборщик не справляется — получаешь знаменитую ошибку OutOfMemoryError: Java heap space. Вот тогда и начинается веселье, блядь, с дампами кучи и прочей шаманской пляской с бубном.