Карта / JVM под капотом / Сборщики мусора (GC)

Сборщики мусора (GC)

Сборщик мусора (GC) — автоматически освобождает память, когда объект больше не нужен. Не нужно вручную вызывать free() как в C/C++. JVM сама отслеживает ссылки и удаляет недостижимые объекты.

Куча делится на поколения — это ключевая идея большинства GC:

Young Generation Eden новые объекты S0 Survivor S1 Survivor promoted Old Generation Tenured долгоживущие Minor GC — часто, быстро Major GC — редко, долго
  • Young Generation — все новые объекты создаются в Eden. Minor GC собирает его часто (каждые секунды) и быстро — большинство объектов умирает молодыми.
  • Выжившие переезжают в Survivor (S0/S1), чередуясь при каждой сборке.
  • Объекты, пережившие несколько сборок, promote в Old Generation.
  • Major GC (Full GC) чистит Old Generation — редко, но с паузой.

Stop-the-world — во время сборки все потоки приложения останавливаются. Цель современных GC — минимизировать эти паузы.

Копнуть глубже

Современные сборщики и их компромисс:

GCПаузыПропускная способностьКогда
G1 (по умолчанию)предсказуемые ~200мсвысокаябольшинство приложений
ZGC< 1мсчуть нижеlow-latency (финтех, игры)
Shenandoah< 10мссредняяальтернатива ZGC
Parallelбольшие паузымаксимальнаяbatch-обработка
Serialбольшие паузынизкаямаленькие приложения

Как GC определяет что объект «мусор». Не через счётчик ссылок (он не работает при циклических ссылках), а через обход графа достижимости:

  1. Начинаем с GC Roots — локальные переменные стека, статические поля, JNI-ссылки.
  2. Обходим все объекты, достижимые из roots.
  3. Всё недостижимое — мусор.

Флаги GC для тюнинга:

-XX:+UseG1GC                    # выбрать G1
-XX:MaxGCPauseMillis=200        # целевая пауза
-Xmx4g -Xms4g                  # размер кучи (фиксируем чтобы не было resize)
-XX:+PrintGCDetails             # логировать GC события

Metaspace (вместо PermGen с Java 8). Метаданные классов раньше хранились в PermGen — куче фиксированного размера, которая переполнялась (OutOfMemoryError: PermGen space). В Java 8 PermGen заменили на Metaspace в нативной памяти — растёт автоматически (ограничен -XX:MaxMetaspaceSize).

🎤 Закрыл тему, если можешь объяснить:
• зачем куча делится на поколения и что такое Minor/Major GC;
• как GC определяет что объект мусор (достижимость vs счётчик ссылок), разницу G1 и ZGC (если дошёл до 2-го слоя).