PHP的“未设置”构造如何在内部工作? [英] How does PHP's 'unset' construct work internally?

查看:124
本文介绍了PHP的“未设置”构造如何在内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前言:我确实知道'未设置'在用户区是如何工作的,但我想知道它是如何在内部工作的。



zval结构,它减少了参考计数器(refcount__gc)。当refcount_gc达到0时,该变量不再使用并且可以被删除。问题是它是否立即总是完成,或者在某些情况下可以由垃圾收集器完成?



我发现了两个矛盾的语句对此:


unset()按照名称说明 - 取消设置变量。它不强制立即释放内存。 PHP的垃圾回收器会在它很快看到适合的意图时执行它,因为无论如何这些CPU周期是不需要的,或者是在脚本内存耗尽之前,无论先发生什么都不要。 - Stackoverflow的答案提及2009年php.net文档


而相反:


当refcount达到零时,zval被销毁并且它所持有的任何内存都是现在免费
- 更好地理解PHP的垃圾收集,2012年文章
a>


那么,我们假设PHP 5.3和PHP 5.5是正确的?如果可能的话,也许你可以在PHP源代码中提供一个未定义定义的链接。谢谢!

TL; DR





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






圆形垃圾收集器



圆形垃圾收集器仅用于循环引用。在这种情况下,refcount__gc永远不会降到零......其他地方仍有一些参考,正常的ZEND_UNSET_ * (星号是ARRAY,OBJ或VAR)不能解除它。所以它必须等待垃圾收集器。



而垃圾收集器只是为了性能原因而定期调用。



< h2> php-src定义

您要求定义ZEND_UNSET_VAR吗? http://lxr.php.net/xref/PHP_5_6/Zend/zend_vm_def .h#4069



以下是减少refcount等主要功能: http://lxr.php.net/xref/PHP_5_6/Zend/zend_execute.h#74



哪一个是正确的?



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

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


Preface: I do know how 'unset' works in the userland, but I would like to find out how it works internally.

When unset is called on zval structure, it decreases the reference counter (refcount__gc). When refcount__gc reaches 0, the variable is no longer used and can be deleted. The question is whether it's always done immediately, or in some cases it can be done later by garbage collector?

I have found two contradictory statements on this:

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

And the opposite:

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

So which one is correct as of let's say PHP 5.3 and PHP 5.5? If possible, maybe you can provide a link to the unset definition in the PHP source code. Thank you!

解决方案

TL;DR

Both statements are true.

Let me explain. (It's true since at least PHP 5.0 (before, I don't know). There comes phpng now, which does fundamental changes, but this principle is still used.)


The cirular garbage collector

The circular garbage collector is just used for circular references. We have them usually when two objects contain references to each other.

As in this case the refcount__gc would never drop to zero… there's still some reference elsewhere, the normal ZEND_UNSET_* (where the asterisk is either ARRAY, OBJ or VAR) cannot unset it. So it has to wait for the garbage collector.

And the garbage collector is only called periodically for performance reasons.

php-src definitions

You asked for the definition of the ZEND_UNSET_VAR? http://lxr.php.net/xref/PHP_5_6/Zend/zend_vm_def.h#4069

And here is the main function for decrementing refcount etc.: http://lxr.php.net/xref/PHP_5_6/Zend/zend_execute.h#74

Which one is correct?

So, if refcount is zero, we are sure that nothing links to it and we can free it. (Second statement: is just talking about the refcount == 0 case)

But, if it's not zero, we mark the variable as to be checked by the circular garbage collector later. (First statement: not necessarily immediately freed)

这篇关于PHP的“未设置”构造如何在内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆