TGViewer
Unity Architect: архитектура unity проектов Unity Architect: архитектура unity проектов @uniarchitect · 5.24K subscribers
Post #91 3.35K
👀🗑Сборка мусора в Unity? Путь GC.Collect().

Давайте проследим некоторый путь. Путь GC.Collect(). Но сначала.
Что такое GC.Collect()? Это принудительный вызов сборки мусора.

Во что превращается GC.Collect? Ведь мы знаем, что Unity использует другой сборщик, который называется Boehm GC, а следовательно GC.Collect должен во что-то транслироваться.
Чтобы ответить на этот вопрос, нужно проследить путь преобразования кода.

1️⃣ Давайте напишем простой класс (Убираю лишние переносы в целях экономии места в посте; Длинные имена, сокращены для простоты чтения ):
public class Minutri : MonoBehaviour {
private void Start() {
GC.Collect();
GC.Collect(2, GCCollectionMode.Forced);
}
}

Два разных вызова — чтобы посмотреть, куда уходит двойка, а куда GCCollectionMode.Forced. GC.Collect(2, GCCollectionMode.Forced) говорит о том, что нужно вызвать сборку вплоть до второго поколения с forced. Но не забываем — мы работаем с Boehm GC. Поэтому про работу с поколениями не может идти речи. Как же получается? Написать так можно — а поколений нет. Смотрите далее)

2️⃣ После трансляции IL2CPP находим метод Start класса Minutri. Называется он у меня Minutri_Start_...

3️⃣ В Assembly-CSharp.cpp наблюдаю, во что превратился метод:
void Minutri_Start_ (Minutri_t* __this, ) {
static bool s_Il2CppMethodInitialized; // <------ а
GC_Collect_m(NULL); // <------ б
GC_Collect_m(2, 1, NULL);
return;

Интересовать нас может сразу два пункта:
а) Видим использование static bool. Напоминаю — это медленно.
б) Оба метода GC_Collect раскрылись, мы их наблюдаем, и они похожи.

4️⃣ Идем глубже, в методы GC_Collect_m...
void GC_Collect_m() {
static bool s_Il2CppMethodInitialized;
L_0 = GC_get_MaxGeneration_m(NULL);
GC_InternalCollect_m(L_0, NULL);
}

а) Опять static bool.
б) Воу 🤨 Все-таки получаем максимальное поколение. Получается, я вам врал! Какой ужас. (нет)
в) Вызываем GC_InternalCollect_m и передаем туда "максимальное поколение".

Давайте я вам помогу, и мы не будем заходить в GC_get_MaxGeneration_m. Он возвращает ноль. Но это и неважно. Сейчас все увидите.

5️⃣ Зайдем глубже, в GC_InternalCollect_m. Мы видим метод. Там опять нам всё не нужно, кроме одной строки:
(()mscorlib::System::GC::InternalCollect) (___0_generation);

Заходим в InternalCollect. Далее в Collect(generation)

6️⃣ Ну что ж. Мы пришли, поздравляю!) Метод Collect перед вами целиком:
void il2cpp::gc::GarbageCollector::Collect(int maxGeneration) {
#if IL2CPP_ENABLE_DEFERRED_GC
if (GC_is_disabled())
s_PendingGC = true;
#endif
GC_gcollect();
}


Тут, как мы видим, всё: последнее упоминание поколений. Глубже мы не пойдем.
Вы видите, чтобы maxGeneration параметр где-то использовался? Вот и я не вижу.
Зачем они так сделали? Вероятней всего для того, чтобы в случае использования другого GC можно было быстро перейти на поколения.

Так, а что у нас с GC.Collect(2, GCCollectionMode.Forced)?
Там пойдут goto и прочие вещи, которые здесь не буду рассматривать, так как не хватит места в посте. Но, короче говоря: в нем будет вызов этого же Collect из пункта 6️⃣. То есть, что бы мы ни указывали в аргументы GC.Collect — это не имеет значения.

Резюмируем:
— GC в .NET C# поколенческий, в Unity - нет
— Вызов сборки мусора конкретного поколения вызывает сборку мусора в целом
— Перегрузки GC.Collect, при настройке билда в IL2CPP не влияют на перформанс и ничего не ломают

P.S. Может быть я был не прав, и мы посмотрели что-то неверно? Давайте, как люди, которые хотят докопаться до сути, обратимся к первоисточнику, и посмотрим на ответ Josh Peterson'а. В ходе диалога, я задал вопрос о том, используют ли юнитеки поколения в Boehm? Был дан ответ:
"Currently Unity does not use the generational GC in Boehm. I suspect that we might be able to use it, but we don't have any active plans to enable that for now".


Анализ трансляции GC.Collect подготовлен специально для @UniArchitect

Об устройстве GC в Unity, о IL2CPP, CI/CD и не только я пишу в своем авторском telegram канале. Подпишись!🔥
  • 👍 36
  • 💯 3
More from @uniarchitect
  1. Jul 24, 2026Post #199
  2. Jul 12, 2026AI НЕ ДЕЛАЕТ ВАС ПРОДУКТИВНЕЕ Незыблемый факт: AI уже очень хорош в маленьких задачах. Нап…
  3. Jul 9, 2026Post #196
  4. Jul 7, 2026UNITY BUILD PIPELINE ПО КИРПИЧИКАМ Полгода назад я решил попробовать активность в блоге, г…
  5. Jul 4, 2026ПРОКЛЯТИЕ ПЕРЕИСПОЛЬЗУЕМОСТИ Делюсь болью. Я последние 5 лет на разных уровнях у разработч…
  6. Jun 29, 2026AI КАК РЕДАКТОР, А НЕ АВТОР Это вторая статья из серии про AI. Первая тут. Когда я запуска…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →