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

Что такое Garbage Collector Roots?

3.0 Senior🔥 111 комментариев
#Управление памятью

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

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

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

Garbage Collector Roots (GC Roots)

Garbage Collector Roots это набор ссылок, которые являются точками входа для сборщика мусора при определении живых объектов в памяти. Это фундаментальный концепт для понимания управления памятью в C#.

Как работает сборка мусора?

Сборщик мусора использует граф объектов:

  1. Находит все GC Roots в памяти
  2. Проходит по графу — определяет все объекты, достижимые из roots
  3. Помечает живые объекты (marked generation)
  4. Удаляет недостижимые объекты и освобождает память

Типы GC Roots

1. Static поля класса

Static переменные всегда считаются GC Roots, потому что они существуют на протяжении всей жизни приложения.

public class GameManager {
    public static GameManager Instance { get; set; }
    private static List<Player> players = new List<Player>();
}

2. Локальные переменные в активных стеках вызовов

Все локальные переменные в текущих методах являются GC Roots.

private void SomeMethod() {
    var enemy = new Enemy();
    var position = new Vector3(0, 0, 0);
    HelperMethod(enemy);
}

3. Экземплярные поля объектов

Если объект является GC Root, то все его поля также считаются живыми.

public class Manager : MonoBehaviour {
    private Player currentPlayer;
    private List<Enemy> enemies;
    
    public void Cleanup() {
        currentPlayer = null;
        enemies = null;
    }
}

4. GameObject в сцене

GameObject всегда GC Root в активной сцене.

5. Объекты с финализаторами

Объекты с методом Finalize становятся GC Roots до вызова финализатора.

Выявление утечек памяти

Проблема: неудалённые подписки

public class Player : MonoBehaviour {
    private void OnEnable() {
        GameEvents.OnEnemyDeath += HandleEnemyDeath;
    }
    
    private void OnDisable() {
        // ЗАБЫЛИ отписаться!
    }
}

Исправление:

private void OnDisable() {
    GameEvents.OnEnemyDeath -= HandleEnemyDeath;
}

Как найти GC Roots?

  1. Window → Analysis → Profiler
  2. Выбери вкладку Memory
  3. Сделай Capture
  4. Найди объект и посмотри Referenced by
  5. Проследи путь до GC Root

Лучшие практики

Правило 1: Минимизируй static поля

// Плохо: static List будет GC Root
private static List<GameObject> pool = new List<GameObject>();

// Хорошо: используй экземплярное поле
private List<GameObject> pool = new List<GameObject>();

Правило 2: Всегда отписывайся от событий

private void OnEnable() {
    Event += Handler;
}

private void OnDisable() {
    Event -= Handler;
}

Правило 3: Очищай коллекции

private void OnDestroy() {
    pool.Clear();
    pool = null;
}

Правило 4: WeakReference для кэшей

Dictionary<string, WeakReference> cache = new Dictionary<string, WeakReference>();

Выводы

GC Roots это точки входа для сборщика мусора. Объект не будет удален, пока на него есть путь из GC Root. Утечки памяти часто происходят из-за неконтролируемых static ссылок и неудаленных подписок. Используй профайлер и всегда очищай ссылки при удалении объектов.