请问在什么情况下 gc_collect_cycles 函数可以发挥作用?在内存使用量即将达到显著水平之前是否应该调用它?
请问在什么情况下 gc_collect_cycles 函数可以发挥作用?在内存使用量即将达到显著水平之前是否应该调用它?
PHP默认启用"Garbage Collector"垃圾回收机制,用于释放“垃圾”所占用的内存。 gc_collect_cycles()
强制回收任何现有的垃圾回路,并返回回收(释放)的循环数(对象、变量值等)。启用Garbage Collector会定期从时间调用此功能来释放资源。在大多数情况下,PHP脚本的生命周期非常短。这种情况下,所有垃圾最终都将在工作结束时被销毁而无需进行任何垃圾回收。
有时需要手动管理GC:
gc_disable()
可以加快一些长时间操作的速度,但也会导致一些内存开销。gc_collect_cycles()
可用于指定GC的正确时刻。使用gc_collect_cycles()
的另一个原因是调试。假设您想要通过memory_get_usage()
来了解某些代码块的内存消耗情况。您需要首先禁用GC,否则您将得到错误结果。之后,您希望分开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()
删除).