402   PHP

以前PHP5.2之前的版本,会存在内存泄露的问题;这和PHP内存回收机制有关;

PHP采用引用计数的方式,确定变量是否被引用;引用一次加1,unset则减1;如果计数为0,则进行内存回收;

但是这种引用计数方式存在一种循环引用的缺陷,比如

$a = array( 'one' );
$a[] =& $a;
xdebug_debug_zval( 'a' );

图示如下:

 

12f37b1c6963c1c5c18f30495416a197-loop-array

 

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

 

图示如下:

 

12f37b1c6963c1c5c18f30495416a197-leak-array

 

 

为了解决这个问题,PHP5.3版本提供了另外一种内存回收的算法。

由于能力有限,暂时看不懂那个算法的原理,大概意思是:

1,设定一个固定大小的根缓冲区

2,当根缓冲区充满时,执行回收算法,遍历根缓冲区的 zval

3,进行模拟删除、模拟恢复、真的删除

 

这种内存回收算法的优点如下:

1、并不是每次引用减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收。

2、可以解决循环引用问题。

3、可以总将内存泄露保持在一个阈值以下。

 

图示如下:

 

0_1279178025eXUy

 

 

PHP5.3以上是默认开启这种内存回收机制的,你也可以手动打开,修改php.ini文件,配置如下

; Enables or disables the circular reference collector.
; http://php.net/zend.enable-gc

zend.enable_gc = On

更多资料




Leave a Reply

Your email address will not be published. Required fields are marked *