哪里可以找到“低内存”和“空闲CPU周期”调用,在unset()上触发垃圾回收?

我经常发现在解释PHP unset()不会立即触发“垃圾收集”时使用以下引用的引用,但只有当它看起来合适时(强调我的):

unset()正如它的名字所说 – 取消设置一个变量。 它不会强制立即释放内存。 PHP的垃圾收集器会在看到拟合时执行它 – 尽快意图,因为无论如何都不需要那些CPU周期 ,或者在脚本耗尽内存之前 ,无论先发生什么。

如果你正在做$ whatever = null; 那么你正在重写变量的数据。 您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取CPU周期,从而导致更长的总体执行时间。

我想知道这个“低内存”和“自由CPU周期”触发垃圾收集的C代码是如何工作的,以及它是否在PHP 5.2.x和PHP 5.3+之间有所不同。

所以我下载了PHP 5.2.17的C源文件,并尝试找到正确的代码部分。 也许我只是失明,或者我的C技能太低,但我找不到这样的代码。

有人能指出我正确的C文件吗?

编辑

在搜索上述引用的例子时,我意识到一些奇怪的东西。

一些示例,如https://stackoverflow.com/a/584982/693207 ,通过使用以下URL对php.net上的评论引用此引用: http : //us2.php.net/manual/en /function.unset.php#86347 。

浏览此URL仅显示unset()手册的顶部。 评论#86347不见了。

检查返回机器显示,该评论DID存在于2008年10月,但在2012年9月或之后的某个时间消失(原因未知)。

也许这句话是,而且一直都是,这是完全错的?

或者有谁在那里,谁能指出我正确的C文件?

好的,所以现在是一些PHP流言终结者的时候了! 请首先阅读关于垃圾收集如何工作的PHP文档,因为我将假设一些关于如何工作的先验知识:

  • 参考计数基础
  • 收集周期

第二个文档具体说明了触发循环垃圾收集器运行的原因。 它与“自由CPU周期”或“低内存”无关 – 它完全基于存在的潜在垃圾对象的数量:

当垃圾收集器打开时,只要根缓冲区运行满,就执行如上所述的循环查找算法。 根缓冲区具有10,000个可能的根的固定大小。

也就是说,无论这些对象的大小如何,循环垃圾收集器都会在累积一定数量的潜在垃圾对象的任何时间运行。 查看zend_gc.c的代码证实了这一点 – 当然没有任何内容可以检查可用内存的总量,并且在CPU空闲时确实没有任何线程可以使GC运行。 所以我认为我们可以将这部分称为“破坏”。


接下来,让我们看一下$x = nullunset($x)之间的实际差异。 首先,让我们确认他们使用这个类作为我们的Buster the Test Dummy做同样的事情:

 class NoisyDestructor { function __destruct() { print "Destructor called\n"; } } 

现在,让我们看看将变量设置为null和unset()之间的区别是什么 – 它是:

 $x = new NoisyDestructor(); print "Created\n"; $x = null; print "Nulled\n"; print "\n"; $x = new NoisyDestructor(); print "Created\n"; unset($x); print "Unset\n"; 

当我们运行它时,我们看到:

 Created Destructor called Nulled Created Destructor called Unset 

等一下 – 这两个都是完全相同的序列! 这两者之间没有function差异。 现在,性能如何?

 class Thing { } $start = microtime(true); for ($i = 0; $i < 1e6; $i++) { $x = new Thing(); $x = null; } printf("%f sec for null\n", microtime(true) - $start); $start = microtime(true); for ($i = 0; $i < 1e6; $i++) { $x = new Thing(); unset($x); } printf("%f sec for unset\n", microtime(true) - $start); 

现在,使用我的笔记本电脑进行测试,使用PHP 5.4,我得到:

 0.130396 sec for null 0.175086 sec for unset 

考虑到我们必须运行此循环以查看此结果的次数,不仅将变量设置为null与取消设置之间的性能差异很小,而且实际上与该注释所声称的完全相反unset()是关于慢了25%! 这个PHP神话已被很好地破坏了。

破获

TL; DR :你发现的报价是完全错误的。 (似乎有可能是因为这个原因而从PHP.net中删除了。)