Поколения объектов: 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
Жизненный цикл объекта
- Объект создаётся в Eden
- Когда Eden заполняется, происходит Minor GC (Young GC)
- Живые объекты из Eden копируются в один из Survivor (например, S0)
- При следующем Minor GC живые объекты из Eden и S0 копируются в S1 (и наоборот)
- Объект, переживший определённое количество 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.