Что такое Garbage Collector (сборщик мусора)?

«Что такое Garbage Collector (сборщик мусора)?» — вопрос из категории Управление памятью, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Garbage Collector (GC) — это компонент среды выполнения .NET (CLR), который автоматически управляет выделением и освобождением памяти для управляемых объектов. Его основная задача — освобождать память, занятую объектами, которые больше не используются приложением.

Как это работает:

  1. Отслеживание ссылок: GC строит граф объектов, начиная с "корней" (глобальные/статические переменные, локальные переменные в активных стеках вызовов, регистры CPU).
  2. Пометка: Помечает все объекты, достижимые из корней, как "живые".
  3. Сборка: Освобождает память, занятую "мертвыми" (недостижимыми) объектами.
  4. Компактизация (опционально): Перемещает оставшиеся живые объекты, чтобы устранить фрагментацию кучи.

Поколения (Generations) для оптимизации:

  • Gen 0: Молодые, недавно созданные объекты. Сборка здесь происходит чаще всего и наиболее быстрая.
  • Gen 1: Объекты, пережившие одну сборку Gen 0. Служит буфером между Gen 0 и Gen 2.
  • Gen 2: Долгоживущие объекты. Сборка здесь наиболее затратная и происходит реже.

Практические следствия и best practices:

  • Не вызывайте GC.Collect() явно. Алгоритм GC сам оптимизирует моменты сборки. Принудительный вызов обычно ухудшает производительность.
  • Используйте IDisposable для немедленного освобождения неуправляемых ресурсов (файловые дескрипторы, сетевое подключение, дескрипторы GDI). Паттерн using — ваш лучший друг.
    using (var fileStream = new FileStream("file.txt", FileMode.Open))
    {
    // Работа с файлом
    } // Dispose() (и, при необходимости, Close()) вызовется автоматически здесь
  • Избегайте долгоживущих ссылок на короткоживущие объекты, так как это может необоснованно "продвинуть" объект в Gen 2.
  • Для высоконагруженных серверных приложений рассмотрите GC.SetGCLatencyMode(GCLatencyMode.LowLatency) или SustainedLowLatency в критичных по задержкам участках кода.