Вопрос проверяет понимание принципов работы сборщика мусора и модели достижимости объектов в JVM.
Garbage Collector считает объект ненужным, если до него нельзя добраться из корневых ссылок.
Корневые ссылки включают локальные переменные стека, статические поля и активные потоки.
Если объект недостижим, он может быть удалён при очередном запуске GC.
GC не удаляет объекты по таймеру или по счётчику ссылок.
Удаление происходит автоматически и недетерминированно.
Чтобы понять логику GC, важно сначала разобраться с понятием достижимости.
Достижимость (reachability) — это возможность добраться до объекта, начиная от корневых ссылок JVM.
GC Roots — это точки входа, от которых GC начинает обход объектов:
локальные переменные и параметры методов в stack
статические поля классов
активные потоки
JNI-ссылки
GC работает по следующей логике:
Берёт все GC Roots
Обходит граф объектов по ссылкам
Помечает все достижимые объекты
Недостижимые объекты считаются мусором
Подсчёт ссылок не подходит из-за:
циклических ссылок
высокой стоимости обновления счётчиков
Наличие ссылки не гарантирует «живость», если она недостижима из GC Roots
GC может не запускаться сразу после потери ссылок
System.gc() не даёт гарантии очистки
Объект считается ненужным не по количеству ссылок, а по факту недостижимости из корней JVM.