Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Garbage Collector Roots (GC Roots)
Garbage Collector Roots это набор ссылок, которые являются точками входа для сборщика мусора при определении живых объектов в памяти. Это фундаментальный концепт для понимания управления памятью в C#.
Как работает сборка мусора?
Сборщик мусора использует граф объектов:
- Находит все GC Roots в памяти
- Проходит по графу — определяет все объекты, достижимые из roots
- Помечает живые объекты (marked generation)
- Удаляет недостижимые объекты и освобождает память
Типы 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?
- Window → Analysis → Profiler
- Выбери вкладку Memory
- Сделай Capture
- Найди объект и посмотри Referenced by
- Проследи путь до 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 ссылок и неудаленных подписок. Используй профайлер и всегда очищай ссылки при удалении объектов.