Sobes.tech
Middle+
113
questionbank

Как происходит работа сборщика мусора на платформе .NET?

Answer from AI

sobes.tech AI

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

Процесс включает:

  • Маркировка (Marking): GC обходит граф корневых ссылок (глобальные переменные, статические поля, стеки потоков) и помечает все доступные из них объекты как живые.
  • Перемещение/Компановка (Relocation/Compacting): GC перемещает живые объекты в непрерывные блоки памяти, освобождая место и уменьшая фрагментацию кучи.
  • Очистка (Sweeping): Память, занимаемая не помеченными (недоступными) объектами, освобождается.

GC в .NET является поколенческим. Куча делится на поколения (0, 1, 2):

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

GC может быть рабочим местом (Workstation GC) или серверным (Server GC).

  • Рабочий GC оптимизирован для интерактивных приложений, может останавливать все потоки приложения (stop-the-world) для сборки.
  • Серверный GC оптимизирован для высокой производительности на многопроцессорных системах, использует несколько выделенных потоков для сборки, минимизируя остановку потоков приложения.
// Пример: создание объектов, которые впоследствии станут недоступными
public class MyObject
{
    public int Data;

    ~MyObject() // Финализатор
    {
        // Этот код выполнится перед тем, как сборщик мусора освободит память
        // Не рекомендуется для большинства случаев из-за непредсказуемости
        Console.WriteLine($"Финализатор вызван для MyObject с данными: {Data}");
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        CreateTemporaryObjects();
        // GC может сработать в любой момент после завершения метода CreateTemporaryObjects
        Console.WriteLine("Объекты созданы. GC может сработать.");

        // Принудительный вызов сборки мусора (не рекомендуется в продакшене)
        GC.Collect();
        GC.WaitForPendingFinalizers(); // Ждем завершения финализаторов

        Console.WriteLine("Сборка мусора выполнена.");
    }

    static void CreateTemporaryObjects()
    {
        for (int i = 0; i < 1000; i++)
        {
            // Создание объекта. После выхода из метода объекты MyObject
            // перестанут быть доступны через локальные переменные.
            MyObject obj = new MyObject { Data = i };
        } // Здесь переменная obj выходит из области видимости
    }
}