Этот вопрос проверяет понимание того, как PHP освобождает память и что происходит при циклических ссылках.
PHP использует подсчёт ссылок: каждое значение хранит число переменных, которые на него указывают. Когда счётчик становится равен нулю, память освобождается. Однако подсчёт ссылок не способен автоматически находить циклические ссылки, поэтому в PHP есть дополнительный механизм GC, который периодически сканирует память и удаляет "циклы". GC работает не постоянно, а запускается по определённым порогам, чтобы не тормозить выполнение.
PHP применяет два механизма: подсчёт ссылок и сборщик циклических ссылок.
Определение: Reference counting — это метод управления памятью, при котором каждое значение хранит число ссылок на себя.
Когда переменная создаётся — счётчик становится равен 1.
Когда переменная копируется — счётчик увеличивается.
Когда переменная удаляется (unset, выход из области видимости) — счётчик уменьшается.
Когда он достигает 0 — память освобождается.
Пример:
php
$a = new StdClass();
$b = new StdClass();
$a->ref = $b;
$b->ref = $a;
Даже если обе переменные удалить, refcount не станет 0 — объекты ссылаются друг на друга.
PHP имеет встроенный сборщик циклических ссылок, который:
периодически (по threshold) сканирует "root buffer"
ищет циклы
уничтожает значения, которые нельзя освободить обычным путём
GC — дорогая операция, поэтому он запускается не всегда, а только при накоплении потенциальных циклических структур.
Сборщик мусора делает PHP безопасным для работы с объектами и сложными структурами данных. Однако важно помнить, что циклы создают нагрузку, и их стоит избегать, когда это возможно.