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