Что такое поколения в GC (young, old, metaspace)?
4. Metaspace → установите MaxMetaspaceSize 5. Generational ZGC (Java 21+) — лучший выбор для low-latency приложений на Java 21+. Для более старых версий используйте G1.
🟢 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
Два наблюдения:
- Для большинства веб-приложений ~90-98% объектов умирают молодыми. Но для задач с большими кэшами это не так.
- Объекты, пережившие несколько сборок, живут долго
Следствие: Разные алгоритмы для разных поколений!
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
- TLAB — аллокация без contention
- Card Table — Minor GC не сканирует Old Gen
- Humongous → увеличьте G1HeapRegionSize
- Metaspace → установите MaxMetaspaceSize
- 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 существуют]]