Вопрос 8 · Раздел 3

Что такое поколения в GC (young, old, metaspace)?

4. Metaspace → установите MaxMetaspaceSize 5. Generational ZGC (Java 21+) — лучший выбор для low-latency приложений на Java 21+. Для более старых версий используйте G1.

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

GC делит память на поколения в зависимости от того, как долго объекты живут.

Простая аналогия: Представьте гардероб:

  • Young Gen — как новая одежда: быстро изнашивается и выбрасывается.
  • Old Gen — как любимая куртка: носите годами.
  • Metaspace — как лекала для пошива одежды. Не сама одежда, а шаблоны, по которым она создаётся.

Три поколения:

Поколение Что хранится Как часто GC
Young Generation Новые объекты Очень часто (каждые секунды)
Old Generation Долгоживущие объекты Редко (каждые минуты)
Metaspace Метаданные классов При заполнении

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

new Object() → Eden (Young)
  ↓ (пережил GC)
Survivor (Young)
  ↓ (пережил ещё несколько GC)
Old Generation

🟡 Middle Level

Weak Generational Hypothesis

Два наблюдения:

  1. Для большинства веб-приложений ~90-98% объектов умирают молодыми. Но для задач с большими кэшами это не так.
  2. Объекты, пережившие несколько сборок, живут долго

Следствие: Разные алгоритмы для разных поколений!

Young Generation

Структура:
  Eden (80%) — сюда попадают все новые объекты
  Survivor S0 (10%) — выжившие
  Survivor S1 (10%) — выжившие

Minor GC:
  1. Eden + S0 → сканируются
  2. Живые объекты → копируются в S1
  3. Eden и S0 очищаются
  4. S0 и S1 меняются ролями

TLAB (Thread Local Allocation Buffer):

Каждому потоку — свой кусок Eden
  → Аллокация без синхронизации!
  → Просто сдвиг указателя

Old Generation

Сюда попадают объекты:
  1. Пережившие 15 сборок (MaxTenuringThreshold)
  2. Большие объекты (сразу в Old)
  3. Когда Survivor переполнен

Full GC — чистит Young + Old
  → Долгая пауза (секунды!)

Metaspace

Java 8+: заменил PermGen
  → Находится в Native Memory (вне Heap)
  → Хранит: классы, методы, константы
  → Растёт динамически

Ограничения:
  -XX:MetaspaceSize=256m  (начальный порог)
  -XX:MaxMetaspaceSize=512m  (максимум)

Card Table оптимизация

Проблема: Minor GC не хочет сканировать весь Old Gen

Решение: Card Table
  → Old Gen разбит на карточки по 512 байт
  → oldObj.field = youngObj → карточка помечается Dirty
  → Minor GC сканирует только Dirty карточки

🔴 Senior Level

TLAB и PLAB

TLAB (Thread Local Allocation Buffer):
  → В Eden, для каждого потока
  → Pointer bumping: obj_ptr += size
  → 0 синхронизации!

PLAB (Promotion Local Allocation Buffer):
  → Аналог в Old Gen
  → Для копирования выживших объектов
  → Избегает contention при продвижении

SATB (Snapshot-At-The-Beginning)

G1 использует SATB для конкурентной разметки:
  → На начало разметки: все живые объекты помечены
  → Если ссылка удаляется во время разметки → объект всё равно жив
  → Floating Garbage: мусор, который соберётся в следующем цикле

Write Barrier для SATB:
  → Перед записью ссылки: сохранить старое значение в buffer
  → Buffer обрабатывается Concurrent Marking

Humongous Objects (G1)

Humongous Objects — объекты больше половины размера региона G1.
Аллоцируются напрямую в Old Gen, минуя Young Gen.

Remembered Sets (RSet) — структура данных в G1, которая отслеживает
ссылки между регионами. Позволяет GC не сканировать весь Heap.

Объект > 50% размера региона → Humongous
  → Сразу в Old Gen
  → Не копируется в Young GC
  → Может вызывать преждевременный GC

Решение: -XX:G1HeapRegionSize=16m или 32m

Generational ZGC (Java 21+)

ZGC стал генерационным!
  → Young и Old поколения
  → Young GC чаще и быстрее
  → Old GC реже
  → -50% CPU overhead vs single-generational

Production Experience

Premature Promotion:

Survivor слишком мал → объекты попадают в Old Gen
  → Old Gen забивается мусором
  → Full GC каждые 5 минут

Решение: увеличить SurvivorRatio или Young Gen

Best Practices

  1. TLAB — аллокация без contention
  2. Card Table — Minor GC не сканирует Old Gen
  3. Humongous → увеличьте G1HeapRegionSize
  4. Metaspace → установите MaxMetaspaceSize
  5. Generational ZGC (Java 21+) — лучший выбор для low-latency приложений на Java 21+. Для более старых версий используйте G1.

Резюме для Senior

  • Young Gen = copying collector, быстрые сборки
  • Old Gen = mark-sweep-compact, медленные сборки
  • Metaspace = native memory, ClassLoader lifecycle
  • TLAB = lock-free аллокация
  • Card Table = оптимизация Minor GC
  • SATB = concurrent marking в G1
  • Humongous = специальные регионы для больших объектов
  • Generational ZGC = будущее low-latency GC

🎯 Шпаргалка для интервью

Обязательно знать:

  • Weak Generational Hypothesis: ~90-98% объектов умирают молодыми → разные алгоритмы для поколений
  • Young Gen: Eden (80%) + Survivor S0 (10%) + Survivor S1 (10%); Minor GC копирует живые между Survivor
  • Old Gen: объекты, пережившие 15 сборок (MaxTenuringThreshold); Full GC чистит Young + Old
  • Metaspace (Java 8+): native memory, хранит метаданные классов; заменил PermGen (был внутри Heap)
  • TLAB — приватный буфер потока в Eden для lock-free аллокации (pointer bumping)
  • Card Table — битовая карта; при записи oldObj.field = youngObj карточка помечается Dirty → Minor GC не сканирует весь Old Gen
  • Premature Promotion: Survivor переполнен → объекты попадают в Old Gen → Full GC

Частые уточняющие вопросы:

  • Почему Young Gen — copying, а Old Gen — mark-sweep? — В Young Gen мусора 98%, копировать 2% эффективно; в Old Gen мусора мало, copying был бы дороже
  • Что такое SATB? — Snapshot-At-The-Beginning: алгоритм G1 для конкурентной разметки; помечает всё, что было живо на начало цикла
  • Зачем 2 Survivor области? — Ping-pong: живые объекты копируются S0→S1→S0, увеличивая age; одна всегда пуста для копирования
  • Почему Metaspace вне Heap? — PermGen (внутри Heap) вызывал частые OOM; Metaspace в native memory, растёт динамически

Красные флаги (НЕ говорить):

  • «Metaspace и PermGen — это одно и то же» — PermGen внутри Heap (фиксированный), Metaspace в native memory (динамический)
  • «Объекты попадают в Old Gen только через age» — Большие объекты и переполнение Survivor тоже
  • «Minor GC чистит Old Gen» — Minor GC только Young Gen; Card Table оптимизация, не полная очистка

Связанные темы:

  • [[4. Что такое Garbage Collection]]
  • [[9. Что такое Young Generation]]
  • [[10. Что такое Old Generation (Tenured)]]
  • [[11. Что такое Metaspace (или PermGen)]]
  • [[12. Какие алгоритмы GC существуют]]