Ответ
Сборщик мусора (GC) определяет объекты для удаления через концепцию достижимости (reachability). Удаляются объекты, которые больше не могут быть достигнуты из так называемых GC Roots.
GC Roots — это "якорные" точки, которые всегда считаются живыми:
- Локальные переменные и параметры в активных стеках потоков.
- Активные Java-потоки (
Threadobjects). - Статические переменные классов.
- Ссылки из JNI (Java Native Interface).
Основной алгоритм: Mark and Sweep
- Mark (Пометка): GC начинает обход графа объектов от всех GC Roots. Все объекты, до которых можно добраться по ссылкам, помечаются как живые.
- Sweep (Очистка): Память сканируется, и все непомеченные объекты считаются мусором и удаляются.
Пример:
public class GCDemo {
public static void main(String[] args) {
// GC Root 1: статическое поле
staticList = new ArrayList<>();
// GC Root 2: локальная переменная в активном стеке
Object localObj = new Object();
Object unreachable = new Object(); // Создан объект
unreachable = null; // Ссылка потеряна -> объект становится мусором
// Вызов GC (подсказка JVM, не гарантия немедленной очистки)
System.gc();
}
static List<Object> staticList; // GC Root
}
Поколенная сборка (Generational Collection) JVM оптимизирует процесс, разделяя объекты по поколениям:
- Young Generation (Eden + Survivor): Сюда попадают новые объекты. Частая, быстрая minor сборка.
- Old Generation (Tenured): Сюда перемещаются объекты, пережившие несколько сборок в Young. Редкая, медленная major/full сборка.
Типы ссылок и их влияние на GC:
- Strong Reference: Обычная ссылка. Объект не будет собран, пока на него есть сильная ссылка.
- SoftReference: Объект будет собран только при нехватке памяти.
- WeakReference: Объект будет собран в следующем цикле GC.
- PhantomReference: Используется для точного контроля над финализацией.