У Алекса появился пост про память. Очень полезный в контексте Unity для разработчиков всех уровней.
Я же хотела рассказать про такой аспект памяти, как ее фрагментация.
О том, как аллоцируются наши кусочки памяти, откуда они берутся и как потом возвращаются - мы очень редко задумываемся. Часто нас интересует сам факт аллоцирования, не больше. Но что происходит, когда мы "отпускаем" ненужный блок памяти? Он просто помечается как неиспользуемый.
Что будет, если мы захотим аллоцировать кусочек побольше? Мы не получим блок, который "освободили" на предыдущем шаге, так как он слишком маленький. Мы получим другой, более большой блок.
А как же тот, маленький?
Это та самая фрагментация. И с этим надо что-то делать.
1️⃣ Например, использовать пулы памяти.
Выделяем большой кусок памяти, режем его на нужные нам кусочки одинакового размера и переиспользуем. Самый простой способ, который при этом очень эффективный.
2️⃣ Аллокаторы. Можно реализовать свои аллокаторы (arena, slab и другие) или взять готовые. Они фактически тоже пулы "под капотом", только более умные и позволяют использовать блоки памяти разного размера.
3️⃣ Аллокаторы с слиянием (coalescing). Еще более умная штуковина с этапом слияния свободных участков и последующим переиспользованием. Используется не так часто, потому что требует дополнительного прохода "упаковки" (да, кое-кого напоминает).
А как же аллокаторы от Unity?
- Temp и Temp Job: обычные arena аллокаторы.
- Persistent: это уже malloc/free и частые аллоцирования приводят к фрагментации.
P.S.: в комментариях уточнили, что persistent - это TLSF аллокатор


