PHP中引用计数指的是什么意思

  介绍

这篇文章将为大家详细讲解有关PHP中引用计数指的是什么意思,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

PHP是什么语言

PHP,一个嵌套的缩写名称,是英文超级文本预处理语言(PHP:超文本预处理器)的缩写。PHP是一种HTML内嵌式的语言,PHP与微软的ASP颇有几分相似,都是一种在服务器端执行的嵌入HTML文档的脚本语言,语言的风格有类似于C语言,现在被很多的网站编程人员广泛的运用。

什么是引用计数

在PHP的数据结构中,引用计数就是指每一个变量,除了保存了它们的类型和值之外,还额外保存了两个内容,一个是当前这个变量是否被引用,另一个是引用的次数。为什么要多保存这样两个内容呢?当然是为了垃圾回收(GC)。

也就是说,当引用次数为0的时候,这个变量就没有再被使用了,就可以通过GC来进行回收,释放占用的内存资源。

任何程序都不能无限制的一直占用着内存资源,过大的内存占用往往会带来一个严重的问题,那就是内存泄露,而GC就是PHP底层自动帮我们完成了内存的销毁,而不用像C一样必须去手动地自由。

怎么查看引用计数?

我们需要安装xdebug扩展,然后使用xdebug_debug_zval()函数就可以看到指定内存的详细信息了,比如:

a 美元;=,“小姐:am  a  String";   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=1, is_ref=0)=& # 39;小姐:am  a 字符串# 39;

从上述内容中可以看的出,这个一美元变量的内容是我一个字符串这样一个字符串。而括号中的refcount就是引用次数,is_ref则是说明这个变量是否被引用。我们通过变量赋值来看看这个两个参数是如何变化的。

b 美元;=,一美元;   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=1, is_ref=0)=& # 39;小姐:am  a 字符串# 39;      $ b =,,一美元;   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=2,, is_ref=1)=& # 39;小姐:am  a 字符串# 39;

当我们进行普通赋值后,refcount和is_ref没有任何变化,但当我们进行引用赋值后,可以看到refcount变成了2,is_ref变成了1。这也就是说明当前的\ $一个变量被引用赋值了,它的内存符号表服务于b美元和美元两个变量。

c 美元;=,,一美元;   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=3,, is_ref=1)=& # 39;小姐:am  a 字符串# 39;      设置($ c, b美元);   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=1, is_ref=1)=& # 39;小姐:am  a 字符串# 39;      $ b =,,一美元;   $ c =,,一美元;   $ b =,“小姐:am  a  String  new";   xdebug_debug_zval(& # 39;一个# 39;);//,,,(refcount=3,, is_ref=1)=& # 39;小姐:am  a  String 新# 39;      设置(美元);   xdebug_debug_zval(& # 39;一个# 39;);//,,,no  such 符号

继续增加一个$ c的引用赋值,可以看到refcount会继续增加,然后设置掉b和c之美元后,refcount恢复到了1,不过这时需要注意的是,is_ref依然还是1,也就是说,这个变量被引用过,这个is_ref就会变成1,即使引用的变量都已经设置掉了这个值依然不变。

最后我们设置掉一美元,显示的就是没有这样的符号了。当前变量已经被销毁不是一个可以用的符号引用了。(注意,PHP中的变量对应的是内存的符号表,并不是真正的内存地址)

对象的引用计数

和普通类型的变量一样,对象变量也是使用同样的计数规则。

//,对象引用计数   class  {      }   $ objA =, new  ();   xdebug_debug_zval (& # 39; objA& # 39;);//,objA:, (refcount=1, is_ref=0)=class  A  {,,}      $ objB =, objA美元;   xdebug_debug_zval (& # 39; objA& # 39;);//,objA:, (refcount=2,, is_ref=0)=class  A  {,,}      $ objC =, objA美元;   xdebug_debug_zval (& # 39; objA& # 39;);//,objA:, (refcount=3,, is_ref=0)=class  A  {,,}      设置($ objB);   class  C {      }   $ objC =, new  C;   xdebug_debug_zval (& # 39; objA& # 39;);//,objA:, (refcount=1, is_ref=0)=class  A  {,,}

不过这里需要注意的是,对象的符号表是建立的连接,也就是说,对美元objC进行重新实例化或者修改为NULL,并不会影响objA美元的内容,这方面的知识我们在之前的对象赋值在PHP中到底是不是引用?文章中已经有过说明。对象进行普通赋值操作也是引用类型的符号表赋值,所以我们不需要加,符号。

PHP中引用计数指的是什么意思