TGViewer
Game Development | YeaHub Game Development | YeaHub @yeahub_game_dev · 370 subscribers
Post #451 149
Разбор вопроса с собеседований "Как работает Garbage Collector?"

Частый вопросы - и довольно стандартный ответ "Он проверяет, ссылается ли что-то на объект. Если нет, то ставит в очередь на удаление".
Но есть более каверзный вопрос, который в последнее время спрашивают довольно часто "Если у нас есть объект A, который ссылается на объект B и объект B, который ссылается на объект A - удалит ли GC эти объекты?".
Казалось бы, всё очевидно. Если GC действительно работает исключительно по ссылкам, то при такой циклической зависимости, у нас объекты не удалятся.
Оказывается нет, потому что GC работает не только по ссылкам, но и по корням.

Корни - это точки входа для поиска живых объектов: локальные переменные в стеке, регистры, статические поля, GC-handle’ы и т.п. GC начинает обход именно от этих корней и идёт по outgoing ссылкам (от объекта к тем, на кого он ссылается). Если никакой корень не ведёт к группе объектов, то эта группа останется не посещённой и будет считаться мусором - даже если внутри группы объекты сильно ссылаются друг на друга.

Раскроем детальнее, что такое outgoing и incoming ссылки.

Outgoing ссылки - это ссылки, которые объект хранит в своих полях/элементах массива и которыми он указывает на другие объекты.
Пример:

class Node { public Node Other; public string Name; }

var a = new Node();
var b = new Node();
a.Other = b; // это outgoing ссылка из a на b
a.Name = "A"; // это поле - не ссылка (если бы Name был object/классом, это был бы outgoing)


Incoming ссылки - это ссылки на сам объект, которые хранят другие объекты или корни.
Пример:

class Owner { public Target T; }
class Target { }

var owner = new Owner();
var t = new Target();
owner.T = t; // здесь owner.T - incoming ссылка для объекта t


Корни - это набор входных точек в граф объектов (локальные переменные, регистры, статические поля, GC-handles, очередь финализаторов и т.д.). GC начинает обход от этих точек и помечает всё достижимое. То, до чего не дошёл - считается недостижимым и может быть собран.

GC начинает с корней и идёт по outgoing ссылкам: он посещает объект, смотрит его поля (outgoing) и переходит к объектам, на которые они указывают. GC не перебирает incoming ссылки напрямую - он просто обнаружит incoming, когда придёт по outgoing ссылке от некоторого уже помеченного объекта.
Поэтому зацикл A и B (A.Outgoing -> B и B.Outgoing -> A) без корней останется непомеченным: у GC нет входной точки, чтобы пойти по outgoing к этим объектам.

Таким образом, ответ - да. GC соберёт эти объекты.

🚀 Пост Guru Unity: @Minerope
  • 👍 1
More from @yeahub_game_dev
  1. Oct 9, 2026#video #unity 📚 FREE Complete Unity Game Development Courses Полный бесплатный курс по ра…
  2. Oct 8, 2026#Собес #lost #update 🤔 Что такое lost update и при каких условиях он возникает? 💬 Кратко…
  3. Oct 7, 2026#Собес #Task #ThreadPool #async 🤔 Как Task использует ThreadPool? 💬 Кратко: Task использ…
  4. Oct 5, 2026#Собес #memory_layout #data_alignment #padding 🤔 Какие есть исключения из правил хранения…
  5. Oct 2, 2026#tool #гит 📚 Хочешь изучить Git, не рискуя своей локальной установкой? Теперь можно запус…
  6. Oct 1, 2026#Собес #docker_rm #container #stop 🤔 Как удалить Docker-контейнер? 💬 Кратко: Чтобы удали…
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 →