Вопрос 17 · Раздел 3

Какие GC минимизируют stop-the-world паузы?

4. ConcGCThreads = cores / 4 5. Избегайте больших массивов 6. SoftMaxHeapSize для возврата памяти

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Low-latency GC — сборщики, которые минимизируют паузы приложения.

Основные:

  • ZGC — паузы < 1 мс (лучший)
  • Shenandoah — паузы < 1 мс
  • G1 — паузы 20-200 мс (компромисс)

Как они это делают:

  • Делают большую часть работы параллельно с приложением
  • Останавливают только для сканирования GC Roots

🟡 Middle Level

Стратегии минимизации

GC Стратегия Пауза
ZGC Colored Pointers + Load Barriers < 1 мс
Shenandoah Load Reference Barriers < 1 мс
G1 Регионы + Mixed GC 20-200 мс

Allocation Stall — опасность

Приложение создаёт мусор быстрее, чем concurrent marking успевает завершить.
Поток приложения блокируется и сам начинает эвакуацию объектов. Опасно: если stalls частые,
throughput падает ещё сильнее, чем с Parallel GC.

Сравнение

GC Типичная пауза CPU overhead Throughput
Parallel 100-1000 мс Минимальный Максимальный
G1 20-200 мс Средний Хороший
ZGC/Shenandoah < 1 мс Высокий -5-15%

Generational ZGC (Java 21+)

Разделение на поколения:
  → -50% CPU overhead
  → Throughput почти как G1
  → Паузы всё ещё < 1 мс

Когда НЕ использовать low-latency GC

❌ При высокой CPU-утилизации барьеры усугубят проблему — приложение тратит больше времени на GC, чем на работу.
❌ Batch processing → паузы не важны
❌ Heap < 4 ГБ → G1 эффективнее

🔴 Senior Level

Concurrent Evacuation

ZGC/Shenandoah перемещают объекты БЕЗ STW:
  → Приложение читает ссылку → Load Barrier
  → Если объект переехал → Self-healing
  → G1: Evacuation = STW (ограничение)

Barrier Overhead

Write Barriers (G1):
  → При каждой записи ссылки
  → ~1-2 ns overhead
  
Load Barriers (ZGC):
  → При каждом чтении ссылки
  → ~5-15 ns overhead
  → Но Self-healing в Fast Path
  
Итог: ZGC медленнее на 5-15%

Tuning для минимизации пауз

# ZGC
-XX:+UseZGC -XX:+ZGenerational
-XX:ConcGCThreads=4
-XX:SoftMaxHeapSize=24g

# G1
-XX:MaxGCPauseMillis=100
-XX:InitiatingHeapOccupancyPercent=45

Best Practices

  1. ZGC (Java 21+) для SLA < 10 мс
  2. G1 для SLA 100-200 мс
  3. Мониторьте Allocation Stall
  4. ConcGCThreads = cores / 4
  5. Избегайте больших массивов
  6. SoftMaxHeapSize для возврата памяти

Резюме для Senior

  • ZGC/Shenandoah = < 1 мс, CPU overhead 5-15% (зависит от workload и Java версии; Generational ZGC имеет другой overhead profile).
  • Concurrent Evacuation = ключ к low latency
  • Allocation Stall = скрытая опасность
  • Generational ZGC = лучший баланс
  • G1 = компромисс для большинства приложений
  • Barrier overhead = цена за низкие паузы

🎯 Шпаргалка для интервью

Обязательно знать:

  • ZGC и Shenandoah: паузы < 1 мс через Concurrent Evacuation (объекты перемещаются БЕЗ STW)
  • ZGC: Colored Pointers + Load Barriers (~5-15 ns overhead при чтении); Shenandoah: Load Reference Barriers (дешевле)
  • G1: Write Barriers (~1-2 ns при записи), паузы 20-200 мс через Mixed GC + регионы
  • Allocation Stall: приложение создаёт мусор быстрее, чем concurrent marking; throughput падает сильнее, чем с Parallel GC
  • Generational ZGC (Java 21+): -50% CPU overhead, throughput почти как G1, паузы всё ещё < 1 мс
  • Когда НЕ использовать low-latency GC: высокая CPU-утилизация (барьеры усугубят), batch processing, Heap < 4 ГБ
  • Tuning: ZGC -XX:ConcGCThreads=4 (cores/4), G1 -XX:MaxGCPauseMillis=100

Частые уточняющие вопросы:

  • Почему ZGC/Shenandoah имеют overhead 5-15%? — Barriers вставляются при каждом чтении/записи ссылки; CPU тратит время на проверки
  • Что будет, если поставить MaxGCPauseMillis=10 мс для G1? — G1 не сможет уложиться → To-space exhausted → Full GC (секунды!)
  • Почему Generational ZGC лучше single-generational? — Young GC чаще и быстрее; -50% overhead; Allocation Stalls почти исчезли
  • Когда G1 лучше ZGC? — SLA 100-200 мс приемлемо, throughput важнее; CPU-bound приложения; Heap < 4 ГБ

Красные флаги (НЕ говорить):

  • «ZGC не имеет overhead» — 5-15% throughput sacrifice за паузы < 1 мс
  • «Allocation Stall не опасен» — throughput падает сильнее, чем с Parallel GC
  • «Low-latency GC всегда лучше» — для batch processing или CPU-bound задач Parallel/G1 эффективнее

Связанные темы:

  • [[14. Что такое ZGC]]
  • [[15. Что такое Shenandoah GC]]
  • [[13. Что такое G1 GC]]
  • [[16. Что такое stop-the-world]]
  • [[12. Какие алгоритмы GC существуют]]