Gymterview
middle

Поколения объектов: Young Generation, Old Generation

Поколения (generations) — это способ разделения heap в JVM на области для объектов разного возраста, основанный на гипотезе о поколениях: большинство объектов умирают молодыми. Это позволяет оптимизировать сборку мусора, собирая короткоживущие объекты часто и дёшево.

Аналогия из жизни: представьте входную корзину для почты (Eden). Новые письма попадают туда. Раз в неделю вы разбираете корзину: ненужное выбрасываете (GC), важное перекладываете в папку (Survivor). Если письмо остаётся важным после нескольких разборов, оно уходит в архив (Old Generation), который разбирают гораздо реже.

Структура heap

Пример
+-----------------------------------------------+
|                   Heap (-Xmx)                  |
+-------------------+---------------------------+
|  Young Generation |     Old Generation        |
|    (-Xmn)         |    (Tenured)              |
+-----+------+------+---------------------------+
| Eden|  S0  |  S1  |          Old               |
+-----+------+------+---------------------------+
  • Eden Space — область создания новых объектов. Большинство объектов здесь и умирают
  • Survivor Space S0 и S1 — две области, между которыми копируются выжившие объекты. В любой момент одна из них пуста
  • Old Generation (Tenured) — содержит объекты, пережившие несколько циклов Minor GC

Жизненный цикл объекта

  1. Объект создаётся в Eden
  2. Когда Eden заполняется, происходит Minor GC (Young GC)
  3. Живые объекты из Eden копируются в один из Survivor (например, S0)
  4. При следующем Minor GC живые объекты из Eden и S0 копируются в S1 (и наоборот)
  5. Объект, переживший определённое количество Minor GC (по умолчанию 15, задаётся -XX:MaxTenuringThreshold), продвигается (promote) в Old Generation

Типы сборок мусора

Тип Что собирает Когда происходит
Minor GC (Young GC) Только Young Generation Eden заполнен
Major GC Только Old Generation Old Generation заполнен (зависит от GC)
Full GC Весь heap + Metaspace Нехватка памяти, System.gc(), нет места для promotion

Термин Major GC иногда используется как синоним Full GC, но строго говоря Major GC собирает только Old Generation, а Full GC — весь heap.

Основные параметры поколений
# Размер Young Generation
-Xmn512m

# Соотношение Old/Young (по умолчанию 2, т.е. Young = 1/3 heap)
-XX:NewRatio=2

# Соотношение Eden/Survivor (по умолчанию 8, т.е. S0 = S1 = 1/10 Young)
-XX:SurvivorRatio=8

# Максимальный возраст для продвижения (по умолчанию 15)
-XX:MaxTenuringThreshold=15

# Включить вывод распределения возрастов
-XX:+PrintTenuringDistribution

Premature Promotion

Если Survivor Space слишком мал, объекты будут продвигаться в Old Generation раньше времени, увеличивая частоту Major/Full GC и снижая производительность.

Частые ошибки

  • Ручное задание -Xmn при использовании G1 — отключает адаптивный подбор размеров
  • Установка MaxTenuringThreshold=0 — все объекты сразу попадают в Old Gen
  • Вызов System.gc() в коде — провоцирует Full GC и может вызвать длительную паузу
  • Слишком маленький Survivor Space — вызывает premature promotion

На собеседовании: объясните гипотезу о поколениях (большинство объектов умирают молодыми), опишите путь объекта: Eden -> Survivor -> Old. Назовите три типа GC (Minor, Major, Full) и когда они происходят. Частая ловушка — вопрос о разнице между Major и Full GC.