这篇文章将为大家详细讲解有关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中到底是不是引用?文章中已经有过说明。对象进行普通赋值操作也是引用类型的符号表赋值,所以我们不需要加,符号。