php垃圾回收机制(gc)介绍

php垃圾回收机制(gc)介绍,第1张

概述php垃圾回收机制(gc)介绍

PHP的编译原理:

ze(Zend engine)调用词法分析器把PHP 代码去空格,注释后分割成一个个token,ze调用语法分析器再对token处理形成opcode,opcode以op array形式存在,ze最后执行op array输出结果。

当一个PHP线程结束时,当前占用的所有内存空间都会被销毁。那么如果这个线程不结束,怎么回收内存呢?

refcount:引用技术器,可以理解为指向该个容器的指针个数吧。

is_ref:是否被引用(只可能是0或者1)

赋值的流程:

<?PHP$a = 'aa';   xdeBUG_deBUG_zval(a);  //(refcount=1, is_ref=0),string 'aa' (length=6)$b = $a; //以下的两个其实是一个变量容器xdeBUG_deBUG_zval(a); //(refcount=2, is_ref=0),string 'aa' (length=6)xdeBUG_deBUG_zval(b); //(refcount=2, is_ref=0),string 'aa' (length=6)unset($b);  //对变量容器 refcount 减1xdeBUG_deBUG_zval(a); //(refcount=1, is_ref=0),string 'aa' (length=6)xdeBUG_deBUG_zval(b); //b: no such symbol  b变量被销毁,指向被断掉,如果对应容器的引用技术为零,那么该块儿内存被回收$b = $a;$b = 'bb';xdeBUG_deBUG_zval(a); //(refcount=1, is_ref=0),string 'aa' (length=6)xdeBUG_deBUG_zval(b); //(refcount=1, is_ref=0),string 'aa' (length=6)  重新申请一个变量容器存储b,a的变量容器引用减1

引用的流程:

<?PHP$a = 'aa';xdeBUG_deBUG_zval('a');  //(refcount=1, is_ref=0),string 'aa' (length=2)$b = & $a;//变量容器的引用技术加1,引用标记置为1xdeBUG_deBUG_zval('a');  //(refcount=2, is_ref=1),string 'aa' (length=2)xdeBUG_deBUG_zval('b');  //(refcount=2, is_ref=1),string 'aa' (length=2)$b = '123'; //PHP会发现,该容器变量是引用(is_ref),所以容器变量不用像赋值那样再申请一个xdeBUG_deBUG_zval('a');  //(refcount=2, is_ref=1),string '123' (length=2)xdeBUG_deBUG_zval('b');  //(refcount=2, is_ref=1),string '123' (length=2)unset($b);//变量容器应用计数减1,引用为零xdeBUG_deBUG_zval('a');  //(refcount=1, is_ref=0),string '123' (length=2)xdeBUG_deBUG_zval('b'); // b: no such symbol

那如果多次引用,unset掉一个,is_ref是否会被置为零,那样BUG不就出现了么?变量容器还是引用啊。那么我们来看看:

<?PHP$a = 'aa';$b = &$a;$c = &$a;//可以看到引用refCount是3,is_ref永远是1xdeBUG_deBUG_zval('a'); //(refcount=3, is_ref=1),string 'aa' (length=2)xdeBUG_deBUG_zval('b'); //(refcount=3, is_ref=1),string 'aa' (length=2)xdeBUG_deBUG_zval('c'); //(refcount=3, is_ref=1),string 'aa' (length=2)unset($b);//我们期待的BUG没有出现,只是refcount减1,is_ref还是1xdeBUG_deBUG_zval('a'); //(refcount=2, is_ref=1),string 'aa' (length=2)xdeBUG_deBUG_zval('b'); // b: no such symbolxdeBUG_deBUG_zval('c'); //(refcount=2, is_ref=1),string 'aa' (length=2)//那PHP它怎么知道这个容器还有引用,毕竟is_ref仍然是1,不能计数,那么现在refcount就起作用了,是它告诉PHP,该变量有几个引用,但问题又来了,如果我干点坏事,在引用的时候,又赋值,它会不会有BUG$e = $a;//我们看到期望的BUG还是没出现,这时候再赋值,就不像直接赋值那么简单refcount加1了,而是申请了一个新的变量容器xdeBUG_deBUG_zval('a'); //(refcount=2, is_ref=1),string 'aa' (length=2)xdeBUG_deBUG_zval('e'); //(refcount=1, is_ref=0),string 'aa' (length=2)

unset和赋值null都能回收变量么?很多人都错认为,这两个都能回收变量空间,其实错了,null只是把变量占用的空间变小了,从回收上来说,该容器依然存在。

<?PHP$a = 'aa';$b = $a;$b = null;//又申请了一个变量容器xdeBUG_deBUG_zval('a');  //(refcount=1, is_ref=0),string 'aa' (length=2)xdeBUG_deBUG_zval('b');  //(refcount=1, is_ref=0),null   变量空间并没被回收unset($b);//这时候才释放了b变量容器的空间xdeBUG_deBUG_zval('a');  //(refcount=1, is_ref=0),string 'aa' (length=2)xdeBUG_deBUG_zval('b');  //b: no such symbol

推荐:PHP视频教程 总结

以上是内存溢出为你收集整理的php垃圾回收机制(gc)介绍全部内容,希望文章能够帮你解决php垃圾回收机制(gc)介绍所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/997856.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存