Reference Counting (Подсчет ссылок): Каждый объект хранит счетчик ссылок на себя. Когда счетчик становится равным нулю, объект считается мусором и удаляется.
Преимущества: Простой, не блокирует выполнение основной программы надолго.
Недостатки: Не справляется с циклическими ссылками; требуется дополнительное пространство для счетчика в каждом объекте.
Tracing Garbage Collectors (Трассирующие сборщики мусора): Начинают с набора "корневых" объектов (например, активных переменных, стека вызовов) и рекурсивно обходят все объекты, доступные из этих корней. Недоступные объекты считаются мусором.
Основные стратегии трассировки:
Mark and Sweep (Пометка и удаление):
Mark (Пометка): Проход по графу объектов, помечая все доступные объекты.
Sweep (Удаление): Второй проход по памяти, удаляя все непомеченные объекты.
Недостатки: Фрагментация памяти.
Mark and Compact (Пометка и уплотнение):
Mark (Пометка): Как в Mark and Sweep.
Compact (Уплотнение): Перемещает живые объекты, чтобы они располагались непрерывно, устраняя фрагментацию.
Недостатки: Более сложный, может требовать остановки выполнения программы.
Copying (Копирование): Разделяет память на две области (полупространства). В каждой итерации сборки мусора, живые объекты из одной области копируются в другую. Затем старая область полностью очищается.
Преимущества: Отсутствие фрагментации, быстрая аллокация памяти после сборки.
Недостатки: Требуется в два раза больше памяти, чем активно используется.
Generational Garbage Collection (Генерационный сбор мусора): Основан на гипотезе о том, что большинство объектов живут недолго. Память делится на поколения (молодое, старое). Объекты помещаются в молодое поколение при создании. Если объект "переживает" несколько сборок мусора в молодом поколении, он перемещается в старое поколение. Сборка мусора происходит чаще в молодом поколении.
Преимущества: Эффективен, так как большая часть работы выполняется в молодом поколении с малым объемом данных.
Недостатки: Требуется отслеживание ссылок из старых поколений на молодые (карточки записи или другие механизмы).
Примеры языков и их GC:
Python: Reference Counting (с циклической сборкой для циклических ссылок).
Java, C#: Generational, Mark and Sweep, Mark and Compact, Copying (различные варианты и комбинации в зависимости от конкретной версии и настроек JVM/.NET).
Go: Concurrent, non-generational Mark and Sweep с оптимизациями.