PHP垃圾回收

来源:互联网 发布:学生会网络技术部职责 编辑:程序博客网 时间:2024/05/29 10:28
①什么是内存泄漏?
描述:内存泄漏具有隐蔽、积累的特性,难检测,原因是内存块未被释放,属于遗漏型缺陷。极端情况会导致系统崩溃。

内存空间三部分:
程序存储区
静态存储区   存全局变量
动态存储区   存储变量

内存泄漏产生原因:开发中在动态存储区存变量,执行完无释放动态分配的存储空间造成内存泄漏。
而垃圾回收能在程序完成时及时释放内存,避免内存泄漏。对于PHP普通的网站是不需要垃圾回收,但如果是脚本长期运行就可能导致内存的泄漏,这时候垃圾回收机制的作用就发挥出来。

②PHP的垃圾回收
描述:
PHP5.2之前采用引用计数方式的内存动态管理,变量引用(refcount=0)时,PHP在内存中销毁该变量,而PHP在一个生命周期就会释放该进程。

PHP5.3后防止引用计数的循环引用如($a = new A();  $a->self = $a;)而导致内存泄漏,引入了垃圾回收机制(就是说PHP5.3开始引入垃圾回收机制)。变量容器zval也变动为如下:
struct _zval_struct {
    /* Variable information */
    zvalue_value value;/* value */ 
    zend_uint refcount__gc; 
    zend_uchar type;/* active type */ 
    zend_uchar is_ref__gc; 
};
我们可以注意到上面变量is_ref(是否引用变量)、refcount(引用的次数) 均添加了__gc 。

PHP5.3的垃圾回收算法:
该算法详细查看http://docs.php.net/manual/zh/features.gc.collecting-cycles.php,以下简说:

PHP5.3的垃圾回收算法以计数为基础,分配一个固定大小的根缓冲区(默认存放10000个zval),并且将所有可能根(变量容器zval)放在缓冲区中,当缓冲区满时,对缓冲区内部所有不同的变量容器执行垃圾回收操作。

PHP5.3垃圾回收注意点:
    1、只有根缓冲区满后在开始垃圾回收。
    2、可以解决循环引用问题。
    3、可以总将内存泄露保持在一个阈值以下。

PHP5.2与PHP5.3内存占用情况:
<?php
class Foo
{
    public $var = '3.1415962654';
}
$baseMemory = memory_get_usage();
for ( $i = 0; $i <= 100000; $i++ )
{
    $a = new Foo;
    $a->self = $a;
    if ( $i % 500 === 0 )
    {
        echo sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "\n";
    }
}




参考:http://docs.php.net/manual/zh/features.gc.performance-considerations.php
          http://www.jianshu.com/p/63a381a7f70c
原创粉丝点击