PHP';s';取消设置';内部构建工作?

PHP';s';取消设置';内部构建工作?,php,garbage-collection,unset,Php,Garbage Collection,Unset,前言:我确实知道“unset”在userland中是如何工作的,但我想了解它在内部是如何工作的 当调用unset时,它会减少引用计数器(refcount\uu gc)。当refcount__gc达到0时,该变量不再使用,可以删除。问题是它是否总是立即完成,或者在某些情况下可以由垃圾收集器稍后完成 我在这方面发现了两种相互矛盾的说法: unset()只执行其名称所说的操作-取消设置变量。它不会强制立即释放内存。PHP的垃圾回收器会在它认为合适的时候做这件事——只要是有意的,因为这些CPU周期无论如

前言:我确实知道“unset”在userland中是如何工作的,但我想了解它在内部是如何工作的

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

我在这方面发现了两种相互矛盾的说法:

unset()只执行其名称所说的操作-取消设置变量。它不会强制立即释放内存。PHP的垃圾回收器会在它认为合适的时候做这件事——只要是有意的,因为这些CPU周期无论如何都不需要,或者在脚本耗尽内存之前,不管最先发生的是什么。-

相反:

当refcount为零时,zval将被销毁,它所持有的任何内存现在都是可用的 -

那么,哪一个是正确的,比如说PHP5.3和PHP5.5?如果可能,您可以在PHP源代码中提供指向unset定义的链接。谢谢大家!

TL;博士 这两种说法都是正确的

让我解释一下。(至少是PHP5.0(以前我不知道),现在有了phpng,它做了根本性的改变,但这个原则仍然在使用。)


环形垃圾收集器 循环垃圾收集器仅用于循环引用。我们通常在两个对象包含相互引用时使用它们

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

而垃圾回收器只是出于性能原因而定期调用

php src定义 你问ZEND_UNSET_VAR的定义

以下是减少参考计数等的主要功能:

哪一个是正确的? 所以,如果refcount为零,我们确信没有任何东西链接到它,我们可以释放它。(第二个语句:只是讨论refcount==0的情况)


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

感谢您的详细回答,基本上我是在寻找递减的refcount和释放内存逻辑,所以这是您提供的第二个链接。据我所知,如果refcount==0,这些是检查中的第76-80行,内存在efree_rel(zval_ptr)中被释放;对的