gpt4 book ai didi

php - PHP 的 'unset' 构造在内部如何工作?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:35:29 25 4
gpt4 key购买 nike

前言:我确实知道“未设置”在用户空间中是如何工作的,但我想了解它在内部是如何工作的。

zval structure 上调用 unset 时,它会减少引用计数器 (refcount__gc)。当 refcount__gc 达到 0 时,该变量不再使用,可以删除。问题是它是总是立即完成,还是在某些情况下可以稍后由垃圾收集器完成?

我发现了两个相互矛盾的陈述:

unset() does just what it's name says - unset a variable. It does not force immediate memory freeing. PHP's garbage collector will do it when it see fits - by intention as soon, as those CPU cycles aren't needed anyway, or as late as before the script would run out of memory, whatever occurs first. - Stackoverflow answer mentioning 2009 php.net documentation

反之:

When the refcount hits zero, the zval is destroyed and any memory that it was holding is now free - Better Understanding PHP’s Garbage Collection, 2012 article

那么在 PHP 5.3 和 PHP 5.5 中哪个是正确的?如果可能,也许您可​​以提供指向 PHP 源代码中未设置定义的链接。谢谢!

最佳答案

长话短说

两种说法都是正确的。

让我解释一下。 (至少从PHP 5.0开始是这样(之前,我不知道)。现在有了phppng,它做了根本性的改变,但仍然沿用这个原理。)


循环垃圾收集器

循环垃圾收集器只是用于循环引用。当两个对象包含对彼此的引用时,我们通常会使用它们。

在这种情况下,refcount__gc 永远不会降为零……其他地方仍然有一些引用,正常的 ZEND_UNSET_*(其中星号是 ARRAY、OBJ 或 VAR)无法取消设置。所以它必须等待垃圾收集器。

并且出于性能原因,垃圾收集器只会定期调用。

php-src 定义

你问的是 ZEND_UNSET_VAR 的定义? http://lxr.php.net/xref/PHP_5_6/Zend/zend_vm_def.h#4069

这里是递减引用计数等的主要函数:http://lxr.php.net/xref/PHP_5_6/Zend/zend_execute.h#74

哪个是正确的?

因此,如果 refcount 为零,我们可以确定没有任何链接指向它,我们可以释放它。 (第二个陈述:只是在谈论 refcount == 0 的情况)

但是,如果它不为零,我们将变量标记为稍后由循环垃圾收集器检查。 (第一个声明:不一定立即释放)

关于php - PHP 的 'unset' 构造在内部如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24557958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com