Получить доступ

GC: алгоритмы и сборщики

Mark-sweep-compact и копирование, stop-the-world и safepoints, конкурентная маркировка, G1 и ZGC и выбор по throughput/latency.

Базовые алгоритмы

Mark-sweep: пометить достижимые, освободить остальное — просто, но оставляет фрагментацию. Mark-compact: после пометки уплотнить живые объекты к началу области — убирает фрагментацию ценой перемещения. Copying: копировать живых в другое пространство — быстро и без фрагментации, но требует резервного места (как в young).

Реальные сборщики комбинируют их: например, copying в молодом поколении и mark-compact в старом.

Три фазы сборки мусора: пометка достижимых объектов, очистка мусора, уплотнение живых объектов.
Mark — пометить достижимое, Sweep — освободить мусор, Compact — уплотнить живые объекты.

Stop-the-world и safepoints

Часть работы GC требует остановки приложения (stop-the-world): чтобы безопасно двигать объекты и менять ссылки, потоки должны замереть в safepoint — заранее определённой точке, где состояние стека согласовано.

Длительность STW-пауз — главный враг латентности. Эволюция сборщиков — это во многом борьба за то, чтобы делать больше работы конкурентно с приложением и сокращать STW.

Конкурентная маркировка

Современные сборщики маркируют живые объекты параллельно с работающим приложением. Проблема: приложение меняет ссылки во время маркировки. Её решают барьерами записи и алгоритмами вроде SATB (snapshot-at-the-beginning) или incremental update, гарантирующими, что ни один живой объект не будет ошибочно собран (tri-color invariant).

Цена конкурентности — небольшой постоянный оверхед на барьерах и возможность «плавающего мусора» (floating garbage), который соберётся в следующий цикл.

Сборщики JVM

Serial — однопоточный, для маленьких куч/контейнеров. Parallel — многопоточный, максимизирует throughput (полезную работу), но с заметными паузами; именно он был дефолтом до JDK 9. G1 (дефолт с JDK 9) делит кучу на регионы, собирает в первую очередь самые «мусорные» (garbage-first) и нацелен на предсказуемые паузы по цели -XX:MaxGCPauseMillis.

ZGC и Shenandoah — конкурентные сборщики со сверхкороткими паузами (суб-миллисекунда), почти не зависящими от размера кучи, за счёт перемещения объектов конкурентно с приложением (colored pointers / load barriers). Устаревший CMS удалён — его не предлагают.

# Пропускная способность важнее пауз (батчи, offline-обработка)
java -XX:+UseParallelGC -Xms4g -Xmx4g -jar app.jar

# Дефолт: сбалансированно, с целью по длительности паузы
java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -Xms4g -Xmx4g -jar app.jar

# Жёсткий SLA по задержке на большой куче
java -XX:+UseZGC -Xms16g -Xmx16g -jar app.jar

# Какой сборщик выбран на самом деле:
java -XX:+PrintFlagsFinal -version | grep -E 'UseG1GC|UseZGC|UseParallelGC'

Какой выбрать

Выбор — это компромисс throughput против latency. Батч/аналитика, где важна общая пропускная способность и паузы терпимы — Parallel. Сервисы с требованиями к задержкам — G1 по умолчанию, а при жёстких SLA на хвостовые задержки и больших кучах — ZGC.

Решение подтверждают измерением (GC-логи, метрики пауз), а не выбирают «на глаз».

Как отвечать на собеседовании

Назовите три базовых алгоритма и их компромиссы (фрагментация/перемещение/резерв), объясните STW через safepoints и зачем конкурентная маркировка с барьерами, и сравните сборщики: Parallel (throughput) → G1 (баланс, дефолт, регионы) → ZGC (суб-мс паузы на больших кучах). Упомяните, что CMS устарел и удалён.

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем