← Назад к вопросам

Какие объекты доступны для сборки мусора

2.0 Middle🔥 151 комментариев
#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие объекты доступны для сборки мусора

Сборка мусора (Garbage Collection) в Java удаляет объекты, которые больше не используются приложением. Для этого JVM нужно определить, какие объекты «недостижимы» из корневых ссылок.

Корневые ссылки (GC Roots)

Объект считается достижимым, если на него есть ссылка (прямо или косвенно) из следующих источников:

  1. Локальные переменные активных потоков — переменные в стеке текущего метода
  2. Статические переменные классов — поля, объявленные как static
  3. JNI References — объекты, используемые из native кода
  4. Объекты, захватываемые внутри JVM — собственные объекты JVM

Объекты доступные для сборки мусора (недостижимые)

public class GCExample {
    public static void main(String[] args) {
        // Объект 1: достижим через переменную obj
        Object obj = new Object();
        
        // Объект 2: создан и на него нет ссылки — недостижим
        new Object();
        
        // Объект 3: была ссылка, но она обнулена
        obj = null; // теперь первый объект недостижим
        
        // Объект 4: доступен только через другую ссылку
        obj = new Object();
        Object ref = obj;
        obj = null; // все еще достижим через ref
    }
}

Типичные сценарии для сборки мусора

1. Выход из области видимости локальной переменной

public void method() {
    if (condition) {
        Object obj = new Object(); // объект создан
    } // объект выходит из области видимости и становится недостижимым
}

2. Обнуление ссылки

Object obj = new Object();
obj = null; // объект больше не достижим

3. Переприсваивание переменной

Object obj = new Object();
obj = new Object(); // первый объект недостижим (если нет других ссылок)

4. Завершение работы потока

new Thread(() -> {
    Object local = new Object(); // доступен только в этом потоке
    // ...
}); // После завершения потока объект также может быть собран

Циклические ссылки НЕ предотвращают сборку мусора

В отличие от некоторых старых языков (C++), Java использует сборщик мусора, который распознает циклические ссылки:

class Node {
    Node next;
}

public void example() {
    Node node1 = new Node();
    Node node2 = new Node();
    
    node1.next = node2;
    node2.next = node1; // циклическая ссылка
    
    node1 = null;
    node2 = null;
    
    // Оба объекта будут собраны, несмотря на циклическую ссылку
    // Это потому, что на них нет ссылок из GC roots
}

Исключение: мягкие и слабые ссылки

Java предоставляет специальные типы ссылок, которые не препятствуют сборке мусора:

import java.lang.ref.*;

// WeakReference — объект может быть собран в любой момент
WeakReference<Object> weak = new WeakReference<>(new Object());

// SoftReference — объект собирается только при нехватке памяти
SoftReference<Object> soft = new SoftReference<>(new Object());

// PhantomReference — самая слабая, для очистки ресурсов
PhantomReference<Object> phantom = new PhantomReference<>(obj, queue);

Как JVM определяет недостижимость

JVM использует алгоритм трассировки (Mark-and-Sweep):

  1. Mark — отмечает все объекты, достижимые из GC roots
  2. Sweep — удаляет неотмеченные (недостижимые) объекты

Объект доступен для сборки мусора, если на него нет ссылок, начиная от GC roots.

Какие объекты доступны для сборки мусора | PrepBro