PHP生成器 - 垃圾收集

时间:2015-12-29 14:15:20

标签: php memory garbage-collection generator php-internals

简单的问题。

何时或如何通过PHP或您自己的生成器销毁它们的堆栈?

采用以下示例:

function doWork(): Generator
{
    // create some objects.
    $o1 = new stdClass();
    $o2 = new stdClass();

    // pause here and wait for data.
    $value = yield 1;

    // By referencing the above objects, they shouldn't destruct.
    $o1->property = $value;
    $o2->property = $value;

    yield $o1;
    yield $o2;

    // End of stack.
}

// Create the generator.
$generator = doWork();

$value = $generator->current(); // $value will equal 1.

if ($x) {
    $generator->send('Hello, World!'); // Continue execution of the generator.
    $o1 = $generator->current();
    $generator->next();
    $o2 = $generator->current();
    $generator->next(); // Complete the generator

    var_dump($o1);
    var_dump($o2);
} else {
    // Do nothing with the generator.
}

// Carry on with script ...

在此示例中,启动生成器并创建两个对象。此时它已被屈服,并且需要进一步的数据。

达到了IF声明。

案例1

如果$x为真,则值"Hello, World!"将被发送到生成器,并且将使用新属性填充对象。

下次读取生成的数据时,将返回对象。

案例2

如果$x为false,则不再使用该生成器。

问题

在案例1中,我希望堆栈像任何其他函数一样关闭,但在案例2中发生器会发生什么?在脚本结束之前,它和所有剩余的对象引用是否都保留在内存中?

或者$generator的引用丢失是否会导致它被清除?

1 个答案:

答案 0 :(得分:5)

生成器破坏其执行上下文(也包括变量表)有两种情况:

  1. 如果生成器完成执行。这可能是通过执行return(包括函数末尾的隐式返回)或执行生成器期间未捕获的异常而发生的。
  2. 如果放弃了对生成器对象的所有引用。
  3. 所以,不,在脚本结束之前,生成器不会生效。一旦$generator变量超出范围,它将被销毁,此时生成器将放弃对变量值和其他执行状态的引用。

    您可以通过在析构函数中创建echo的类然后将此类实例化为局部变量来轻松地观察销毁顺序。