参考:
https://www.cnblogs.com/taijun/p/4206770.html
https://zhuanlan.zhihu.com/p/170598213
垃圾回收机制简介
垃圾回收机制(gc)顾名思义,是一种动态存储分配的方案。它会自动释放程序不再需要的已分配的内存块。
PHP使用了引用计数(reference counting)GC机制,同时使用根缓冲区机制,当php发现有存在循环引用的zval时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,以此解决循环引用导致的内存泄漏问题。
- 1. 如果引用计数减少到零,所在变量容器将被清除(free),不属于垃圾;
- 2. 如果一个zval的引用计数减少后还大于0,那么它会进入垃圾周期。其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾。
每个对象都内含一个引用计数器refcount,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为 NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。
回收机制控制
1,配置项
默认的,PHP的垃圾回收机制是打开的,然后有个php.ini设置允许你修改它:zend.enable_gc 。
2,相关函数
除了修改配置zend.enable_gc ,也能通过分别调用gc_enable() 和 gc_disable()函数在运行php时来打开和关闭垃圾回收机制。
//强制收集所有现存的垃圾循环周期 gc_collect_cycles();#删除垃圾 //停用循环引用收集器 gc_disable();#相当于停止垃圾回收,可以加快一些长时间的操作,但也会导致一些内存开销 //激活循环引用收集器 gc_enable();#开启垃圾回收 //返回分配给 PHP 的内存量 memory_get_usage()
变量调试
引用计数调试,php7以后
<?php echo '测试字符串引用计数'; $a = "new string"; $b = $a; xdebug_debug_zval( 'a' );//0 unset( $b); xdebug_debug_zval( 'a' );//0 $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' );
性能影响
1、内存占用空间的节省
首先,实现垃圾回收机制的整个原因是为了一旦先决条件满足,通过清理循环引用的变量来节省内存占用。
在PHP执行中,一旦根缓冲区满了或者调用gc_collect_cycles() 函数时,就会执行垃圾回收。
2、执行时间增加
垃圾回收影响性能的第二个领域是它释放已泄漏的内存耗费的时间。
通常,PHP中的垃圾回收机制,仅仅在循环回收算法确实运行时会有时间消耗上的增加。但是在平常的(更小的)脚本中应根本就没有性能影响。
3、允许更多这种脚本同时运行
在平常脚本中有循环回收机制运行的情况下,内存的节省将允许更多这种脚本同时运行在你的服务器上。因为总共使用的内存没达到上限。