php7垃圾回收机制l_php7垃圾回收机制浅析

今天本来想着了解下php的垃圾回收机制,看了下php手册里的描述,大致了解了垃圾回收机制的原理,想着自己写代码去测试下,是不是跟手册里说的是一样的。然后就有了这篇文章。

发现问题

按照手册的实例代码敲了下,发现了神奇的问题,结果不一样啊!

$a = "new String";

xdebug_debug_zval( 'a' );

手册告诉我们的结果是:

a: (refcount=1, is_ref=0)='new string'

我自己的结果:

a: (interned, is_ref=0)='new String'

这个是什么东东?

原来我的PHP版本是7.1,但是手册上是5.3的。那我明白了,PHP7在垃圾回收机制上做了优化。如果我是大牛,我就去看源码了,可惜我不是!所以咱只能查资料了,找了大半天,发现很多标题都是PHP7垃圾回收机制的文章,但是里面的内容确还是PHP5的垃圾回收机制的内容,要么就是直接上源码!这。。。我要是能看懂源码,还需要你去复制一遍吗?

经过坚持不懈的搜索,查找到了这篇文章---PHP7中zval的变化

解决问题

原文:

In PHP 7 a zval can be reference counted or not. There is a flag in the zval structure which determined this.

There are some types which are never refcounted. These types are null, bool, int and double.

There are other types which are always refcounted. These are objects, resources and references.

And then there are types, which are sometimes refcounted. Those are strings and arrays.

For strings the not-refcounted variant is called an “interned string”. If you’re using an NTS (not thread-safe) PHP 7 build, which you typically are, all string literals in your code will be interned. These interned strings are deduplicated (i.e. there is only one interned string with a certain content) and are guaranteed to exist for the full duration of the request, so there is no need to use reference counting for them. If you use opcache, these strings will live in shared memory, in which case you can’t use reference counting for them (as our refcounting mechanism is non-atomic). Interned strings have a dummy refcount of 1, which is what you’re seeing here.

For arrays the not-refcounted variant is called an “immutable array”. If you use opcache, then constant array literals in your code will be converted into immutable arrays. Once again, these live in shared memory and as such must not use refcounting. Immutable arrays have a dummy refcount of 2, as it allows us to optimize certain separation paths.

翻译:

在PHP7中,zval结构体中有一个标志来决定zval是否能被引用计数。

像null,bool,int,double这些变量类型永远不会被引用计数(这个地方可能有些不太严谨,鸟哥的博客中写道PHP7中zval的类型共有18种,其中IS_LONG,IS_DOUBLE,IS_NULL,IS_FALSE,IS_TRUE不会使用引用计数)。

像object,resources,references这些变量类型总是会使用引用计数。

然而,像array,strings这些变量类型有时会使用引用计数,有时则不会。

不使用引用计数的字符串类型被叫做“interned string(保留字符串)”。如果你使用一个NTS(非线程安全)的PHP7来构建,通常情况下,代码中的所有字符串文字都将是限定的。这些保留字符串都是不可重复的(即,只会存在一个含有特定内容的保留字符串)。它会一直存在直到请求结束时才销毁,所以也就无需进行引用计数。如果使用了 opcache 的话,保留字符会被存储在共享内存中,在这种情况下,无法使用引用计数(因为我们引用计数的机制是非原子的)。保留字符串的伪引用计数为1。

对于数组来说,无引用计数的变量称为“不可变数组”。如果使用opcache,则代码中的常量数组文字将转换为不可变数组。同样的,他们存在于共享内存中,因此不得使用引用计数。不可变数组的伪引用数为2,因为它允许我们优化某些分离路径。

总结

PHP7的垃圾回收机制已经做过了优化。当有人问我们PHP垃圾回收机制的时候,我们不能再按手册上解释的那样去回答,而是要分版本去解释,当然,这篇只是简单的解释了PHP7中zval的变化,暂时没有办法去深入的解释PHP7的垃圾回收机制。主要原因还是咱的技术水平还有待提高,源码解释那部分看的云里雾里的,还需要更多时间去学习,以后会看懂了再来填这个坑吧。这篇文章主要先做个mark。当然也希望有能力的大佬看到的话,可以指教一下我

参考资料

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值