
Убейте GC-спайки в играх и сервисах: коллекции без аллокаций на .NET
arhip1986 18 минут назад Убейте GC-спайки в играх и сервисах: коллекции без аллокаций на .NET 8 мин 453 .NET * C# * Разработка игр * Высоконагруженные системы * Алгоритмы * Туториал Каждый разработчик на .NET...
Вот важная новость с фронта ИИ: arhip1986 18 минут назад Убейте GC-спайки в играх и сервисах: коллекции без аллокаций на . NET * C# * Разработка игр * Высоконагруженные системы * Алгоритмы * Туториал Каждый разработчик на . NET сталкивался с этим.
Всё работает быстро, но иногда случается внезапный фриз. Игра проседает с 60 до 30 FPS на секунду. Сервис отвечает на запрос 100 мс вместо обычных 10.
Технические детали
Виновник — Garbage Collector. Когда GC решает собрать мусор, он останавливает все потоки приложения (Stop-The-World). Для игр и real-time сервисов это катастрофа.
Стандартные коллекции . NET создают мусор везде:// Каждая из этих операций аллоцирует память var list = new List(); // аллокация list. Add(42); // может аллоцировать при росте capacity var result = list.
Where(x => x > 10); // аллокация итератора var arr = list. ToArray(); // аллокация массива list. Clear(); // O(N) — обход массива, но не аллокацияВ типичном игровом кадре может быть сотни таких операций.
Отраслевые последствия
Мусор накапливается, GC собирает его в самый неподходящий момент — во время босс-файта. Что с этим делают обычноПодходПроблемыОграничивать аллокации вручнуюОчень сложно, легко ошибитьсяИспользовать ArrayPoolНеудобно, нет поддержки Dictionary/HashSet, нужно вручную возвращатьИспользовать struct и SpanНе покрывает все сценарии (словари, хеш-сеты)Unity Collections + BurstРаботает только в Unity, сложный APIСвои пулыДолго писать и отлаживать, особенно для сложных коллекцийРешение: GC-free коллекции с пулингом и знакомым APIGcFreeCollections — библиотека для . 0+ и Unity, которая заменяет стандартные коллекции на их GC-free аналоги.
dotnet add package GcFreeCollections --version 1. 0Ключевые возможности:PooledList — замена List без аллокаций после прогреваPooledDictionary — замена DictionaryPooledHashSet — замена HashSetPooledQueue, PooledStack, PooledPriorityQueuePooledMemoryStream — замена MemoryStreamPooledStringBuilder — замена StringBuilder с меньшим числом аллокацийPooledQuery — LINQ-пайплайн без аллокацийHotPath. Enter() — отлавливает случайные аллокации в DEBUGLeak tracking — находит утечки пулированных объектовReference Quarantine — безопасная очистка через Maintain()Чем отличается от стандартных коллекцийХарактеристикаListPooledListАллокация при созданииЕсть (new List())Нет (берётся из пула)Аллокация при добавлении элементовЕсть (при росте capacity)Нет после прогрева (capacity фиксирован или пул расширяется)Аллокация при Clear()Нет, но O(N) обходНет, O(1) (Hot-first Clear)Возврат памятиТолько когда GC соберётЯвный возврат в пул (Dispose)Отслеживание утечекНетДа (LogLeaks)Защита от аллокаций в hot pathНетДа (HotPath.
Enter)Ключевое отличие: стандартные коллекции оперируют на уровне "создал-использовал-забыл-пусть-GC разбирается". GcFreeCollections — "взял-из-пула-использовал-вернул-в-пул". Подключение пространства имёнusing GcFreeCollections;Шаг 2.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.





