php 编译原理,php垃圾回收机制以及php的编译原理

php垃圾回收机制以及php的编译原理

发布时间:2020-03-27 11:04:33

来源:亿速云

阅读:545

作者:小新

今天小编给大家分享的是php垃圾回收机制以及php的编译原理,很多人都不太了解,今天小编为了让大家更加了解php,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。

de44a44d5b36952d4400f79b647c2fea.png

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 symbol

xdebug_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的编译原理就分享到这里了,当然并不止以上和大家分析的办法,不过小编可以保证其准确性是绝对没问题的。希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值