Какие алгоритмы GC существуют
В виртуальной машине Java необходимо четко различать теоретические базовые алгоритмы очистки памяти (фундаментальные подходы) и конкретные реализации сборщиков мусора (Garbage C...
🟢 Junior Level
В виртуальной машине Java необходимо четко различать теоретические базовые алгоритмы очистки памяти (фундаментальные подходы) и конкретные реализации сборщиков мусора (Garbage Collectors) в JVM HotSpot, которые комбинируют эти алгоритмы для разных поколений кучи.
3 базовых алгоритма очистки памяти
| Алгоритм | Принцип работы | Плюсы | Минусы | Где применяется |
|---|---|---|---|---|
| Copying (Копирование) | Память делится на две зоны. Живые объекты копируются из активной зоны в свободную, а старая зона очищается целиком. | Исключительная скорость, нулевая фрагментация | Требует двойного запаса памяти | Young Generation (Eden $\rightarrow$ Survivor) |
| Mark-Sweep (Разметка и удаление) | 1. Разметка: обход графа от GC Roots и маркировка живых объектов. 2. Очистка: удаление неразмеченных объектов. |
Не требует перемещения объектов, экономен по памяти | Высокая фрагментация: память покрывается изолированными «дырами» | Старые сборщики Old Gen (CMS) |
| Mark-Compact (Разметка и уплотнение) | 1. Разметка живых объектов. 2. Сдвиг всех выживших объектов в начало региона единым плотным монолитом. |
Нулевая фрагментация: восстанавливает быстрый bump-the-pointer | Долгие паузы Stop-The-World (многопроходный пересчет ссылок) | Full GC в G1 и Parallel Old |
Бытовая аналогия
- Copying: Переезд в новую отремонтированную квартиру: вы забираете с собой только нужные вещи, а старую квартиру с мусором отдаете под снос.
- Mark-Sweep: Пройти по комнате с мусорным пакетом и выкинуть фантики из углов. Вещи остались на местах, но на полу образовались хаотичные пустоты.
- Mark-Compact: Выбросить фантики, а всю оставшуюся мебель плотно сдвинуть к одной стене, освободив сплошное свободное пространство.
🟡 Middle Level
Палитра сборщиков мусора в HotSpot JVM
Виртуальная машина предоставляет набор готовых сборщиков под разные типы нагрузок:
┌────────────────────────────────────────────────────────────────────────┐
│ СБОРЩИКИ МУСОРА В HOTSPOT │
├─────────────────┬──────────────┬──────────────┬────────────────────────┤
│ Сборщик мусора │ Паузы (STW) │ Throughput │ Рекомендуемое применение│
├─────────────────┼──────────────┼──────────────┼────────────────────────┤
│ Serial GC │ 100–500 мс │ Низкий (1 CPU)│ Микроконтейнеры, CLI │
│ Parallel GC │ 100–1000 мс │ Максимум │ Batch, Big Data, Hadoop│
│ G1 GC (Def) │ 20–200 мс │ Высокий │ Web-сервисы, Spring Boot│
│ ZGC │ < 1 мс │ Средний (-10%)│ HFT, FinTech, Real-time│
│ Shenandoah │ < 10 мс │ Средний (-10%)│ Альтернативный low-lat │
│ Epsilon GC │ 0 мс (нет GC)│ Абсолютный │ Бенчмарки, Lambdas │
└─────────────────┴──────────────┴──────────────┴────────────────────────┘
Треугольник компромиссов GC (Trade-off Triangle)
Невозможно создать сборщик мусора, идеальный по всем параметрам. Архитектурный выбор всегда диктуется компромиссом между тремя факторами:
Latency (Минимальные паузы)
▲
/ \
/ \
Throughput ◄───────┴───────► Footprint
(Пропускная способность) (Оверхед по памяти/CPU)
- Parallel GC жертвует Latency (длинные паузы) ради максимального Throughput (все 100% CPU отдаются расчету данных).
- ZGC жертвует Throughput (тратит 5–15% CPU на барьеры чтения) ради ультранизкого Latency (паузы $< 1$ мс).
- G1 GC — золотая середина: адаптивно балансирует паузы и пропускную способность для большинства enterprise-задач.
🔴 Senior Level
Трехцветная разметка (Tri-Color Marking)
В основе всех современных параллельных и конкурентных сборщиков (G1, ZGC, Shenandoah) лежит абстракция трех цветов:
┌────────────────────────────────────────────────────────┐
│ ⚪ БЕЛЫЙ: Непосещенный объект. В конце фазы разметки │
│ все оставшиеся белые объекты — это МУСОР. │
├────────────────────────────────────────────────────────┤
│ 🔘 СЕРЫЙ: Объект посещен, но его дочерние поля-ссылки │
│ еще не просканированы сборщиком. │
├────────────────────────────────────────────────────────┤
│ ⚫ ЧЕРНЫЙ: Объект гарантированно жив, и ВСЕ его поля │
│ успешно просканированы. │
└────────────────────────────────────────────────────────┘
Проблема конкурентной разметки (Lost Object Problem):
Во время параллельной работы приложения поток выполнения (Mutator) может перепривязать ссылку:
- Поток забирает ссылку на Белый объект $C$ у Серого объекта $B$.
- Поток записывает ссылку на этот Белый объект $C$ в поле Черного объекта $A$.
- Поскольку объект $A$ уже черный, сборщик к нему не вернется. Серый объект $B$ ссылку потерял.
- Катастрофа: Живой объект $C$ остался белым и будет ошибочно уничтожен сборщиком мусора!
Решение проблемы: SATB vs Incremental Update vs Load Barriers
Разные GC решают проблему потери объектов принципиально разными механизмами:
1. SATB (Snapshot-At-The-Beginning) — используется в G1:
- Применяет Write Barrier (Барьер записи): перед тем как затереть старую ссылку в
B.field = null, JVM перехватывает старое значение ссылки на объект $C$ и принудительно помещает его в локальный буфер разметки. - Объект $C$ помечается серым и гарантированно выживает.
- Trade-off: Возникает Floating Garbage (Плавающий мусор): если объект $C$ действительно больше никому не нужен, он все равно переживет текущий цикл сборки.
2. Incremental Update — использовался в CMS:
- При добавлении ссылки на белый объект в черный
A.field = C, Write Barrier перекрашивает черный объект $A$ обратно в Серый, заставляя GC повторно просканировать его поля перед финишем.
3. Load Barriers (Барьеры чтения) — используется в ZGC:
- Перехватывает не запись, а чтение ссылки
Object o = a.field;. - Проверяет метаданные цвета указателя (Colored Pointers). Если объект перемещается, Load Barrier на лету обновляет указатель прямо в потоке (Self-Healing), делая процесс эвакуации полностью прозрачным для приложения.
Epsilon GC: No-Op сборщик мусора
Включенный флагом -XX:+UseEpsilonGC, этот сборщик реализует только интерфейс аллокатора памяти.
- При вызове
newон инкрементирует указатель кучи (Bump-the-pointer). - Он никогда не собирает мусор. Когда куча заполняется, процесс немедленно падает с
java.lang.OutOfMemoryError: Java heap space. - Зачем нужен в реальном мире:
- Изолированные микро-бенчмарки (JMH): измерение чистой производительности кода без помех от фоновых потоков GC.
- Serverless-функции (AWS Lambda / Knative): микросервисы с временем жизни в несколько секунд, которым гарантированно хватает 256 МБ кучи на время выполнения одного запроса.
🎯 Шпаргалка для интервью
30-секундный ответ (Elevator Pitch)
«Базовые алгоритмы сборки мусора включают: Copying (быстрое копирование выживших без фрагментации, применяется в Young Gen), Mark-Sweep (разметка и удаление, вызывает фрагментацию памяти) и Mark-Compact (уплотнение со сдвигом объектов, устраняющее фрагментацию ценой пауз STW). В HotSpot эти алгоритмы объединены в готовые сборщики: Parallel GC (максимальный throughput для пакетных задач), G1 GC (сбалансированный стандарт Java 9+ с региональной структурой и адаптивными паузами), и сверхбыстрые ZGC / Shenandoah (паузы $< 1$ мс за счет конкурентного уплотнения с барьерами чтения). Для предотвращения потери живых объектов при конкурентной разметке G1 использует алгоритм SATB, а ZGC — Load Barriers».
3–4 каверзных вопроса с ответами
- В чем разница между базовыми алгоритмами GC и конкретными сборщиками в HotSpot?
- Ответ: Базовые алгоритмы (Copying, Mark-Sweep, Mark-Compact) — это теоретические методы обхода и очистки памяти. Сборщики мусора в HotSpot (Parallel, G1, ZGC) — это сложные программные подсистемы, которые комбинируют эти алгоритмы для разных поколений памяти, управляя параллелизмом, планированием потоков, барьерами памяти и компромиссами между пропускной способностью (Throughput) и паузами (Latency).
- Что такое трехцветная разметка (Tri-Color Marking) и как G1 предотвращает ошибочное удаление объектов?
- Ответ: Объекты делятся на Белые (непосещенные, кандидаты на мусор), Серые (посещенные, поля не проверены) и Черные (живые, все поля проверены). Если поток приложения стирает ссылку на белый объект у серого и передает ее черному, сборщик может не заметить живой белый объект и удалить его. G1 решает эту проблему через алгоритм SATB (Snapshot-At-The-Beginning): барьер записи перехватывает факт удаления ссылки и принудительно помечает старый белый объект как серый, сохраняя снимок графа на начало сборки.
- Чем принципиально отличаются барьеры записи (Write Barriers) в G1 от барьеров чтения (Load Barriers) в ZGC?
- Ответ: Write Barrier в G1 срабатывает при модификации ссылок в объектах (
obj.field = newRef), помечая грязные страницы в Card Table или буферизируя старые ссылки для SATB. Load Barrier в ZGC срабатывает при разыменовании ссылки (Ref r = obj.field). Если ссылка указывает на еще не перемещенный объект во время конкурентной эвакуации, Load Barrier на лету обновляет ссылку в памяти на новый адрес (self-healing), позволяя перемещать объекты без глобальных пауз Stop-The-World.
- Ответ: Write Barrier в G1 срабатывает при модификации ссылок в объектах (
- В каких сценариях Parallel GC предпочтительнее современного ZGC или G1?
- Ответ: В сценариях пакетной обработки данных (Batch Processing, Big Data ETL, научные вычисления, компиляция), где задержки ответа (Latency) не имеют значения, а критична только общая скорость завершения задачи. Parallel GC не тратит циклы CPU на фоновые барьеры чтения/записи и многопоточную синхронизацию разметки, обеспечивая максимально возможный Throughput на доступных ядрах процессора.
Типичные ошибки и Red Flags
- 🚩 Утверждение: «ZGC всегда во всех сценариях лучше, чем Parallel GC или G1» (ZGC жертвует 5–15% Throughput и требует больше памяти на барьеры; для пакетных задач Parallel эффективнее).
- 🚩 Смешивание понятий базового алгоритма (Mark-Sweep) и готового сборщика (G1 GC).
- 🚩 Заблуждение: «Epsilon GC можно использовать в качестве обычного легковесного сборщика в проде» (Epsilon вообще не очищает память и гарантированно упадет с OOM при заполнении кучи).
- 🚩 Непонимание механики барьеров памяти (Write Barriers vs Load Barriers).
Связанные темы
- Что такое Garbage Collection — базовые понятия и цели GC
- Что такое G1 GC — подробный разбор работы G1
- Что такое ZGC — ультранизкие задержки и Load Barriers
- Что такое Shenandoah GC — альтернатива ZGC от Red Hat
- Что такое stop-the-world — природа глобальных пауз