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

Когда объект удаляется сборщиком мусора?

1.8 Middle🔥 81 комментариев
#Память и Garbage Collector

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

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

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

Когда объект удаляется сборщиком мусора?

Сборщик мусора (GC) в .NET удаляет объект, когда он становится недостижимым — то есть когда на него нет ни одной живой ссылки из корневых объектов (roots) или других активных объектов.

Процесс сборки мусора в .NET

  1. Фаза маркировки (Mark) — GC проходит по всем живым объектам, начиная с корней (стек, статические поля, handles), и отмечает их как доступные
  2. Фаза удаления (Sweep) — объекты, которые не отмечены, считаются мусором и удаляются
  3. Фаза уплотнения (Compact) — оставшиеся объекты сдвигаются в памяти для улучшения локальности

Когда точно удаляется объект?

public class MyClass
{
    public void DoSomething() { }
}

public class Program
{
    static void Main()
    {
        MyClass obj = new MyClass();  // объект создан
        obj.DoSomething();
        
        obj = null;  // ссылка обнулена
        
        // obj всё ещё может быть в памяти!
        // Удаление произойдёт на ближайшей сборке мусора
        
        GC.Collect();  // принудительная сборка (НЕ рекомендуется!)
        // Теперь объект гарантированно удалён
    }
}

Важный момент: обнуление ссылки (obj = null) — это только условие для удаления, а не гарантия! Объект не удаляется мгновенно.

Генерации в .NET

.NET использует поколенческую модель GC (generational):

  • Gen 0 — новые объекты, проверяется часто
  • Gen 1 — пережившие одну сборку
  • Gen 2 — пережившие две сборки (долгоживущие)

Объекты, которые долго остаются недостижимыми в Gen 2, удаляются при полной сборке мусора.

Деструкторы и Finalize

Если у объекта есть деструктор, он попадает в специальную очередь finalization:

public class MyClass
{
    ~MyClass()  // деструктор
    {
        Console.WriteLine("Объект удаляется");
    }
}

static void Main()
{
    var obj = new MyClass();
    obj = null;
    
    // 1. Объект помечен как недостижимый
    // 2. GC добавляет его в очередь finalization
    // 3. Finalization поток вызывает деструктор
    // 4. ЗАТЕМ объект удаляется из памяти
}

IDisposable — явное управление ресурсами

Для своевременного освобождения ресурсов используй IDisposable:

public class FileManager : IDisposable
{
    private FileStream _file;
    private bool _disposed = false;
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _file?.Dispose();
            }
            _disposed = true;
        }
    }
    
    ~FileManager() => Dispose(false);
}

static void Main()
{
    using (var manager = new FileManager())
    {
        // использование
    }  // Dispose вызвана гарантированно
}

Ключевые выводы

  • Объект удаляется, когда нет живых ссылок
  • Это происходит на ближайшей сборке мусора, а не мгновенно
  • Используй IDisposable для немедленного освобождения ресурсов
  • Избегай принудительных GC.Collect() — это снижает производительность
  • Деструкторы замедляют работу GC, используй их редко
Когда объект удаляется сборщиком мусора? | PrepBro