Может кто-нибудь объяснить, при каких обстоятельствах функция gc_collect_cycles может быть полезна? Должна ли она быть вызвана до того, как произойдет существенное использование памяти?
По умолчанию PHP имеет «Garbage Collector». Он используется для освобождения памяти, используемой «мусором». gc_collect_cycles()
заставляет собирать любые существующие циклы мусора. Он возвращает количество собранных (освобожденных) циклов (объекты, значения переменных …). Enabled Garbage Collector периодически вызывает эту функцию, чтобы освободить ресурсы. В большинстве случаев PHP-скрипт живет очень короткое время. В этом случае вся мусор будет уничтожен в конце работы без сбора мусора.
Иногда необходимо вручную управлять GC:
gc_disable()
может ускорить некоторые длительные операции, но также приводит к некоторым накладным расходам памяти. 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()
) .