php 常见的三种缓存(PHP进阶学习之垃圾回收机制详解)
php 常见的三种缓存
PHP进阶学习之垃圾回收机制详解本文实例讲述了php垃圾回收机制。分享给大家供大家参考,具体如下:
一、概念
垃圾回收机制是一种动态存储分配的方案。它会自动释放程序不再需要的已分配的内存块。垃圾回收机制可以让程序员不必过分关心程序内存分配,从而将更多的精力投入到业务逻辑。在现在的流行各种语言当中,垃圾回收机制是新一代语言所共有的特征,如python、php、c#、ruby等都使用了垃圾回收机制。
二、php垃圾回收机制
1、在php5.3版本之前,使用的垃圾回收机制是单纯的“引用计数”。即:
①每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器+1;
②当变量引用撤掉后(执行unset()后),计数器-1;
③当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。
并且php在一个生命周期结束后就会释放此进程/线程所占的内容,这种方式决定了php在前期不需要过多考虑内存的泄露问题。
但是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时候,这一组内存对象已经没用了,但是不能回收,从而导致内存泄露的现象。
php5.3开始,使用了新的垃圾回收机制,在引用计数基础上,实现了一种复杂的算法,来检测内存对象中引用环的存在,以避免内存泄露。
2、随着php的发展,php开发者的增加以及其所承载的业务范围的扩大,在php5.3中引入了更加完善的垃圾回收机制,新的垃圾回收机制解决了无法处理循环的引用内存泄漏问题。
如官方文档所说:每个php变量存在一个叫"zval"的变量容器中。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息。第一个是"is_ref",是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过使用&来使用自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。第二个额外字节是"refcount",用以表示指向这个zval变量容器的变量(也称符号即symbol)个数。所有的符号存在一个符号表中,其中每个符号都有作用域(scope)。简单的理解如下图所示:
如官方文档所说,可以使用xdebug来检查引用计数情况:
|
<?php $a = "new string" ; $c = $b = $a ; xdebug_debug_zval( 'a' ); unset( $b , $c ); xdebug_debug_zval( 'a' ); ?> |
以上例程会输出:
a: (refcount=3, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'
注意:从php7的nts版本开始,以上例程的引用将不再被计数,即$c=$b=$a之后a的引用计数也是1.具体分类如下:
在php 7中,zval可以被引用计数或不被引用。在zval结构中有一个标志确定了这一点。
①对于null,bool,int和double的类型变量,refcount永远不会计数;
②对于对象、资源类型,refcount计数和php5的一致;
③对于字符串,未被引用的变量被称为“实际字符串”。而那些被引用的字符串被重复删除(即只有一个带有特定内容的被插入的字符串)并保证在请求的整个持续时间内存在,所以不需要为它们使用引用计数;如果使用了opcache,这些字符串将存在于共享内存中,在这种情况下,您不能使用引用计数(因为我们的引用计数机制是非原子的);
④对于数组,未引用的变量被称为“不可变数组”。其数组本身计数与php5一致,但是数组里面的每个键值对的计数,则按前面三条的规则(即如果是字符串也不在计数);如果使用opcache,则代码中的常量数组文字将被转换为不可变数组。再次,这些生活在共享内存,因此不能使用refcounting。
我们的demo例子如下:
|
<?php echo '测试字符串引用计数' ; $a = "new string" ; $b = $a ; xdebug_debug_zval( 'a' ); unset( $b ); xdebug_debug_zval( 'a' ); $b = & $a ; xdebug_debug_zval( 'a' ); echo '测试数组引用计数' ; $c = array ( 'a' , 'b' ); xdebug_debug_zval( 'c' ); $d = $c ; xdebug_debug_zval( 'c' ); $c [2]= 'c' ; xdebug_debug_zval( 'c' ); echo '测试int型计数' ; $e = 1; xdebug_debug_zval( 'e' ); |
看到的输出如下:
可以参考:https://stackoverflow.com/questions/34764119/confusion-about-php-7-refcount
三、回收周期
默认的,php的垃圾回收机制是打开的,然后有个php.ini设置允许你修改它:zend.enable_gc 。
当垃圾回收机制打开时,算法会判断每当根缓存区存满时,就会执行循环查找。根缓存区有固定的大小,默认10,000,可以通过修改php源码文件zend/zend_gc.c中的常量gc_root_buffer_max_entries,然后重新编译php,来修改这个值。当垃圾回收机制关闭时,循环查找算法永不执行,然而,根将一直存在根缓冲区中,不管在配置中垃圾回收机制是否激活。
除了修改配置zend.enable_gc ,也能通过分别调用gc_enable() 和 gc_disable()函数在运行php时来打开和关闭垃圾回收机制。调用这些函数,与修改配置项来打开或关闭垃圾回收机制的效果是一样的。即使在可能根缓冲区还没满时,也能强制执行周期回收。你能调用gc_collect_cycles()函数达到这个目的。这个函数将返回使用这个算法回收的周期数。
允许打开和关闭垃圾回收机制并且允许自主的初始化的原因,是由于你的应用程序的某部分可能是高时效性的。在这种情况下,你可能不想使用垃圾回收机制。当然,对你的应用程序的某部分关闭垃圾回收机制,是在冒着可能内存泄漏的风险,因为一些可能根也许存不进有限的根缓冲区。因此,就在你调用gc_disable()函数释放内存之前,先调用gc_collect_cycles()函数可能比较明智。因为这将清除已存放在根缓冲区中的所有可能根,然后在垃圾回收机制被关闭时,可留下空缓冲区以有更多空间存储可能根。
四、性能影响
1、内存占用空间的节省
首先,实现垃圾回收机制的整个原因是为了一旦先决条件满足,通过清理循环引用的变量来节省内存占用。在php执行中,一旦根缓冲区满了或者调用gc_collect_cycles()
函数时,就会执行垃圾回收。
2、执行时间增加
垃圾回收影响性能的第二个领域是它释放已泄漏的内存耗费的时间。
通常,php中的垃圾回收机制,仅仅在循环回收算法确实运行时会有时间消耗上的增加。但是在平常的(更小的)脚本中应根本就没有性能影响。
3、在平常脚本中有循环回收机制运行的情况下,内存的节省将允许更多这种脚本同时运行在你的服务器上。因为总共使用的内存没达到上限。
这种好处在长时间运行脚本中尤其明显,诸如长时间的测试套件或者daemon脚本此类。同时,对通常比web脚本运行时间长的脚本应用程序,新的垃圾回收机制,应该会大大改变一直以来认为内存泄漏问题难以解决的看法。
希望本文所述对大家php程序设计有所帮助。
原文链接:https://blog.csdn.net/dream_successor/article/details/78678760
- php秒杀实现代码(php无限极分类实现方法分析)
- php工作原理及功能(php设计模式之适配器模式原理、用法及注意事项详解)
- php在没有命名空间之前是怎么调(php命名空间设计思想、用法与缺点分析)
- php获取socket连接的详细信息(php使用socket调用http和smtp协议实例小结)
- php验证码图解(php/JS实现的生成随机密码验证码功能示例)
- win7如何搭建php环境(阿里云Win2016安装Apache和PHP环境图文教程)
- php怎么设计状态模式(php设计模式之观察者模式定义与用法经典示例)
- php内存占用分析(PHP基础之输出缓冲区基本概念、原理分析)
- php依赖注入对象注册(php依赖注入知识点详解)
- 宝塔linux面板php7.0安装不上(宝塔面板php.ini文件在哪里找)
- 解释php中可变变量并举例说明(PHP Primary script unknown 解决方法总结)
- php扩展库使用教程(php使用pecl方式安装扩展操作示例)
- php获取数组中和为指定数的数组(php统计数组不同元素的个数的实例方法)
- php去水印方法(PHP开发的文字水印,缩略图,图片水印实现类与用法示例)
- php面向对象教程理解(PHP面向对象程序设计之构造方法和析构方法详解)
- php验证码思路(PHP实现字母数字混合验证码功能)
- 被鉴定的古董价值300万 当心,你可能遇到诈骗了(被鉴定的古董价值300万)
- 英语难学吗(初中英语难学吗)
- 如何追女孩子(如何追女孩子的技巧和方法)
- 是不是快乐全被你拿走了(而是你得到的)
- 世界上只有妈妈好(世界上只有妈妈好的歌词)
- 为什么现在社会越来越卷了(现在社会为什么发展那么快呢)
热门推荐
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9