PHP 生成器 - 垃圾收集

Posted

技术标签:

【中文标题】PHP 生成器 - 垃圾收集【英文标题】:PHP Generators - Garbage Collection 【发布时间】:2016-04-03 10:41:31 【问题描述】:

简单的问题。

生成器何时或如何通过 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 为假,则不再使用生成器。

问题

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

或者是否丢失了对$generator 的引用导致它,并且内部的所有引用都被清除了?

【问题讨论】:

wiki.php.net/rfc/generators#closing_a_generator 【参考方案1】:

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

    如果生成器完成执行。这可能通过执行 return(包括函数末尾的隐式返回)或通过生成器执行期间未捕获的异常来发生。 如果对生成器对象的所有引用都已放弃。

所以,不,生成器在脚本结束之前不会存在。一旦$generator 变量超出范围,它将被销毁,此时生成器将放弃对变量值和其他执行状态的引用。

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

【讨论】:

以上是关于PHP 生成器 - 垃圾收集的主要内容,如果未能解决你的问题,请参考以下文章

为啥 PHP 的垃圾收集器会降低性能,没有它如何管理内存?

PHP垃圾收集澄清

PHP 的垃圾收集机制是怎样的

过早收集资源垃圾

基于PHP Memcache(d)的会话:是否应禁用垃圾收集?

简单说明PHP的垃圾收集机制是怎样的?