Питання 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 існують]]