Питання 9 · Розділ 3

Що таке Young Generation?

4. Eden очищується

Мовні версії: English Russian Ukrainian

🟢 Junior Level

Young Generation — область Heap, куди потрапляють усі нові об’єкти.

Навіщо окремий Young Gen: ~90-98% об’єктів умирають швидко. Копіювальний збирач ефективний для цього патерну: копіюємо тільки живі об’єкти (2%), мертві просто ігноруємо.

Проста аналогія: “Дитячий садок” для об’єктів. Більшість об’єктів “умирають” тут дуже швидко.

Структура:

  • Eden — тут створюються нові об’єкти
  • Survivor 0 та Survivor 1 — сюди потрапляють ті, що вижили після GC

Minor GC (збірка молодого покоління):

  1. Eden заповнився → запускається GC
  2. Мертві об’єкти видаляються
  3. Живі копіюються в Survivor
  4. Eden очищується

Чому швидко: 98% об’єктів мертві → копіюються тільки 2%


🟡 Middle Level

Алокація: TLAB

Кожному потоку → свій TLAB в Eden
  TLAB = 64 КБ ексклюзивної пам'яті

Алокація:
  pointer += object_size  // Bump-the-pointer
  → Швидше ніж malloc() в C++!

Життєвий цикл

new Object() → Eden
  ↓ Minor GC
Survivor (age +1)
  ↓ Minor GC (age +1)
Survivor (age +2)
  ↓ ... (до age = 15)
Old Generation

Premature Promotion

Проблема: Survivor переповнений
  → Об'єкти виштовхуються в Old Gen
  → Old Gen забивається сміттям
  → Full GC!

Рішення: збільшити SurvivorRatio або Young Gen

Тюнінг

-Xmn2g                     # Фіксований Young Gen
-XX:SurvivorRatio=8        # Eden:Survivor = 8:1
-XX:MaxTenuringThreshold=15  # Вік перед Old Gen

🔴 Senior Level

PLAB (Promotion Local Allocation Buffer)

При Minor GC: об'єкти, що вижили, копіюються в Survivor/Old
  → PLAB = TLAB для копіювання
  → Кожен GC потік має свій PLAB
  → Уникає contention при евакуації

PLAB (Promotion Local Allocation Buffer) — аналог TLAB для Old Gen.
Потік копіює об'єкти з Survivor в Old Gen через свій приватний буфер,
без синхронізації.

G1 Humongous Regions

Об'єкт > 50% регіону → Humongous
  → Одразу в Old Gen (не в Eden!)
  → Не копіюється в Minor GC
  → Економить ресурси на марному копіюванні

Humongous Regions — регіони G1 для об'єктів > 50% розміру регіону.
Алокуються напряму в Old Gen.

PrintTenuringDistribution

-XX:+PrintTenuringDistribution

# Вивід:
 Desired survivor size: 10 MB
 Age 1: 5000 objects, 40000 bytes
 Age 2: 2000 objects, 16000 bytes
 ...
 Age 15: 100 objects, 800 bytes

→ Допомагає налаштувати MaxTenuringThreshold

Best Practices

  1. TLAB — алокація майже безкоштовна
  2. Уникайте Premature Promotion
  3. G1 Humongous → збільште G1HeapRegionSize
  4. Для G1: не фіксуйте -Xmn — G1 сам адаптивно змінює розмір Young Gen. Для Serial/Parallel GC фіксація -Xmn може бути корисною.
  5. Моніторте tenuring distribution

Резюме для Senior

  • Young Gen = copying collector, O(живі об’єкти)
  • TLAB/PLAB = lock-free алокація/евакуація
  • Premature Promotion = головний ворог продуктивності
  • Humongous Objects = одразу в Old Gen
  • G1 адаптивно змінює розмір Young Gen

🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • Young Gen = Eden (80%) + Survivor S0 (10%) + Survivor S1 (10%)
  • Усі нові об’єкти створюються в Eden; Minor GC копіює живі в Survivor, Eden очищується
  • TLAB (Thread Local Allocation Buffer) — приватний буфер потоку в Eden, алокація = pointer bumping (0 синхронізації)
  • PLAB (Promotion Local Allocation Buffer) — аналог TLAB для Old Gen при евакуації об’єктів, що вижили
  • MaxTenuringThreshold = 15 (за замовчуванням); об’єкт потрапляє в Old Gen після 15 зборок
  • Premature Promotion: Survivor переповнений → об’єкти виштовхуються в Old Gen → Full GC
  • Humongous Objects (G1): об’єкт > 50% регіону → одразу в Old Gen, не копіюється в Minor GC

Часті уточнюючі запитання:

  • Чому Minor GC такий швидкий? — 98% об’єктів в Eden мертві; копіюються тільки 2% живих (O(живі), не O(все))
  • Що робить -XX:+PrintTenuringDistribution? — Показує розподіл об’єктів за age; допомагає налаштувати MaxTenuringThreshold
  • Чому не варто фіксувати -Xmn для G1? — G1 адаптивно змінює розмір Young Gen для досягнення MaxGCPauseMillis; фіксація ламає адаптивність
  • Що таке SurvivorRatio? — Відношення Eden:Survivor (за замовчуванням 8:1); замалий → Premature Promotion

Червоні прапорці (НЕ говорити):

  • «Усі об’єкти живуть довго, Young Gen непотрібний» — Weak Generational Hypothesis вірна для більшості додатків
  • «Фіксую -Xmn для G1, щоб контролювати пам’ять» — G1 втрачає адаптивність, паузи стають непередбачуваними
  • «Minor GC сканує Old Gen» — Card Table оптимізація: скануються тільки Dirty картки

Пов’язані теми:

  • [[8. Що таке покоління в GC (young, old, metaspace)]]
  • [[10. Що таке Old Generation (Tenured)]]
  • [[13. Що таке G1 GC]]
  • [[2. Що зберігається в Heap]]
  • [[12. Які алгоритми GC існують]]