以前PHP5.2之前的版本,会存在内存泄露的问题;这和PHP内存回收机制有关;
PHP采用引用计数的方式,确定变量是否被引用;引用一次加1,unset则减1;如果计数为0,则进行内存回收;
但是这种引用计数方式存在一种循环引用的缺陷,比如
$a = array( 'one' ); $a[] =& $a; xdebug_debug_zval( 'a' );
图示如下:

这时候 $a 被引用了两次,即使 unset($a) , 引用计数减1,依然不为零,即无法回收 $a 占用的内存,出现内存泄露的问题。
图示如下:

为了解决这个问题,PHP5.3版本提供了另外一种内存回收的算法。
由于能力有限,暂时看不懂那个算法的原理,大概意思是:
1,设定一个固定大小的根缓冲区
2,当根缓冲区充满时,执行回收算法,遍历根缓冲区的 zval
3,进行模拟删除、模拟恢复、真的删除
这种内存回收算法的优点如下:
1、并不是每次引用减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收。
2、可以解决循环引用问题。
3、可以总将内存泄露保持在一个阈值以下。
图示如下:

PHP5.3以上是默认开启这种内存回收机制的,你也可以手动打开,修改php.ini文件,配置如下
; Enables or disables the circular reference collector. ; http://php.net/zend.enable-gc zend.enable_gc = On
Leave a Reply