gc_collect_cycles函数有什么用途?

26

请问在什么情况下 gc_collect_cycles 函数可以发挥作用?在内存使用量即将达到显著水平之前是否应该调用它?


这个有帮助吗?http://php.net/manual/zh/features.gc.collecting-cycles.php - Mike B
似乎gc_collect_cycles只有在GC被禁用时才真正有用。 - user2864740
1个回答

30

PHP默认启用"Garbage Collector"垃圾回收机制,用于释放“垃圾”所占用的内存。 gc_collect_cycles() 强制回收任何现有的垃圾回路,并返回回收(释放)的循环数(对象、变量值等)。启用Garbage Collector会定期从时间调用此功能来释放资源。在大多数情况下,PHP脚本的生命周期非常短。这种情况下,所有垃圾最终都将在工作结束时被销毁而无需进行任何垃圾回收。

有时需要手动管理GC:

  1. gc_disable() 可以加快一些长时间操作的速度,但也会导致一些内存开销。
  2. 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()删除).


谢谢 @clover! 我一直在想如何释放一些资源。这太聪明、太容易了! - GTodorov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接