Какая функция gc_collect_cycles полезна?

Может кто-нибудь объяснить, при каких обстоятельствах функция gc_collect_cycles может быть полезна? Должна ли она быть вызвана до того, как произойдет существенное использование памяти?

По умолчанию PHP имеет «Garbage Collector». Он используется для освобождения памяти, используемой «мусором». gc_collect_cycles() заставляет собирать любые существующие циклы мусора. Он возвращает количество собранных (освобожденных) циклов (объекты, значения переменных …). Enabled Garbage Collector периодически вызывает эту функцию, чтобы освободить ресурсы. В большинстве случаев PHP-скрипт живет очень короткое время. В этом случае вся мусор будет уничтожен в конце работы без сбора мусора.

Иногда необходимо вручную управлять GC:

  1. gc_disable() может ускорить некоторые длительные операции, но также приводит к некоторым накладным расходам памяти.
  2. gc_collect_cycles() может использоваться для указания правильных моментов GC.

Еще одна причина использования gc_collect_cycles() – отладки. Предположим, вы хотите знать, каково потребление памяти для некоторого блока кода с помощью memory_get_usage() . Сначала вам нужно отключить GC, в другом месте вы получите неправильные результаты. После этого вы хотите отделить время, затраченное GC и вашим приложением. Поэтому вызовите gc_collect_cycles() и измерьте тайминги / память до и после.

Маленький пример:

 class A { public $ref; public $name; public function __construct($name) { $this->name = $name; echo($this->name.'->__construct();'.PHP_EOL); } public function __destruct() { echo($this->name.'->__destruct();'.PHP_EOL); } } gc_disable(); $a1 = new A('$a1'); $a2 = new A('$a2'); $a1->ref = $a2; $a2->ref = $a1; $b = new A('$b'); $b->ref = $a1; echo('$a1 = $a2 = $b = NULL;'.PHP_EOL); $a1 = $a2 = $b = NULL; echo('gc_collect_cycles();'.PHP_EOL); echo('// removed cycles: '.gc_collect_cycles().PHP_EOL); echo('exit();'.PHP_EOL); 

Вывод:

 $a1->__construct(); $a2->__construct(); $b->__construct(); $a1 = $a2 => $b = NULL; $b->__destruct(); gc_collect_cycles(); $a2->__destruct(); $a1->__destruct(); // removed cycles: 4 

Это означает, что только $b был уничтожен, когда его попросили. Другие $a1 и $a2 имеют циклические ссылки, и его свойства name также потребляют память. Два объекта + две строки = 4 (удалены gc_collect_cycles() ) .