Когда сборщик мусора (GC) очищает кучу (Heap) в Java?

«Когда сборщик мусора (GC) очищает кучу (Heap) в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сборка мусора — недетерминированный процесс, инициируемый JVM. Точный момент нельзя предсказать.

Основные триггеры для запуска GC:

  1. Нехватка памяти в куче: Когда для выделения нового объекта недостаточно свободного места в Young Generation (Eden space).
  2. Заполнение поколений: Объекты, пережившие несколько сборок в Young Gen, перемещаются в Old Generation. Когда она заполняется, запускается Major GC (более долгая).
  3. Явный запрос: Вызов System.gc() — это лишь намек рантайму, выполнение не гарантировано.
  4. Внешние факторы: Некоторые сборщики (как G1) могут работать по расписанию или на основе прогнозируемых пауз.

Пример жизненного цикла объекта:

// 1. Объект создается в Eden space
List<String> data = new ArrayList<>();

// 2. Ссылка обнуляется, объект становится "кандидатом" на удаление
data = null;

// 3. В НЕКОТОРЫЙ момент GC определит его как недостижимый и освободит память
// System.gc(); // Плохая практика в production-коде

Ключевые принципы:

  • Объект удаляется, только если он недостижим от любых GC Roots (потоки, статические поля, локальные переменные в стеке).
  • Сборка часто вызывает STW (Stop-The-World) паузы, когда потоки приложения приостанавливаются.
  • Современные GC (ZGC, Shenandoah) стремятся минимизировать эти паузы.

Вывод: Программист управляет достижимостью объектов (обнуляя ссылки), но не моментом запуска GC.