ENIGMA AI
ENIGMA AI

Как работает сборщик мусора?

встречается 15× middle language_specific

Как ответить

Сборщик мусора (GC) автоматически освобождает память, занятую объектами, на которые больше нет ссылок из корневых точек (стек, статические поля, JNI). В Java и .NET используется поколенческая гипотеза: большинство объектов живут недолго, поэтому кучу делят на молодое и старое поколения. Это позволяет собирать молодое поколение часто и быстро, а старое — реже.

Рассмотрим на примере HotSpot JVM. Молодое поколение состоит из Eden и двух Survivor-областей (S0, S1). Новые объекты попадают в Eden. Когда он заполняется, происходит minor GC: живые объекты копируются в S0, а Eden очищается. При следующем minor GC объекты из Eden и S0 копируются в S1, счётчик возраста увеличивается. Объекты, пережившие несколько циклов (по умолчанию 15), перемещаются в Old Generation. Когда Old заполняется, запускается major GC — он может быть mark-sweep или mark-compact, в зависимости от выбранного алгоритма.

Основные алгоритмы сборки:

  • Mark-Sweep — обходит граф объектов, помечает живые, затем удаляет мёртвые. Оставляет фрагментацию.
  • Mark-Compact — после разметки сдвигает живые объекты в начало области, устраняя фрагментацию. Требует остановки приложения (stop-the-world).
  • Copying — используется в молодом поколении: живые объекты копируются в другую область, старая очищается целиком. Быстро, но требует дополнительной памяти.

Типы GC в Java:

  • Serial — однопоточный, подходит для маленьких приложений с кучей до ~100 МБ. Паузы могут быть длинными.
  • Parallel — многопоточный, ориентирован на пропускную способность. Хорош для бэка, где важна скорость обработки, а не паузы.
  • CMS (Concurrent Mark-Sweep) — старался минимизировать паузы, но страдал от фрагментации и «promotion failure». Устарел.
  • G1 (Garbage First) — делит кучу на регионы (по 1–32 МБ), собирает регионы с наибольшим количеством мусора. Паузы предсказуемы, обычно < 10 мс. Стандартный с Java 9.
  • ZGC — с Java 11 (экспериментальный), паузы < 1 мс независимо от размера кучи. Использует цветные указатели и concurrent перемещение.

Пример настройки JVM для G1 с целевой паузой 5 мс:

-XX:+UseG1GC -XX:MaxGCPauseMillis=5 -Xms2g -Xmx2g

Все GC останавливают приложение (stop-the-world) на время разметки корней и некоторых фаз. Современные сборщики (G1, ZGC) делают большую часть работы конкурентно, сокращая паузы до миллисекунд. Выбор GC зависит от требований: для высоконагруженных систем с большими кучами подходит G1 или ZGC, для пакетной обработки — Parallel.

Ключевые тезисы

  • Сборка мусора основана на анализе достижимости объектов от корневых точек (GCRoots).
  • Поколенческая гипотеза: объекты в молодом поколении собираются часто и быстро, старое — реже.
  • Основные алгоритмы: Mark-Sweep, Mark-Compact, Copying. Каждый имеет компромиссы по скорости и фрагментации.
  • Типы GC в Java: Serial, Parallel, CMS, G1, ZGC — отличаются целями (пропускная способность vs. низкие паузы).
  • Stop-the-world паузы неизбежны, но современные GC (G1, ZGC) минимизируют их до миллисекунд.

Что спросят дальше

  • — Чем отличается CMS от G1? Почему CMS устарел?
  • — Как настроить размер кучи и выбрать GC под приложение с низкими задержками (например, онлайн-игра)?
  • — Что такое утечка памяти в управляемых языках и как её диагностировать (heap dump, profiler)?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение