PHP1-php垃圾回收机制

为了避免内存泄露,需要探究php垃圾回收机制。

一 写时复制

function cow()
{
    $a='仙士可'.time();
    $b=$a;
    $c=$a;
//这个时候内存占用相同,$b,$c都将指向$a的内存,无需额外占用

    $b='仙士可1号';
//这个时候$b的数据已经改变了,无法再引用$a的内存,所以需要额外给$b开拓内存空间

    $a='仙士可2号';
//$a的数据发生了变化,同样的,$c也无法引用$a了,需要给$a额外开拓内存空间
    xdebug_debug_zval('a');
    xdebug_debug_zval('b');
    xdebug_debug_zval('c');
}

二 引用计数

function refcount()
{
    $a = '仙士可'.time();
    $b = $a;
    $c = $a;

    xdebug_debug_zval('a');
    xdebug_debug_zval('b');
    xdebug_debug_zval('c');

    $b='仙士可2号';
    xdebug_debug_zval('a');
    xdebug_debug_zval('b');

    echo "脚本结束\n";
}

三 引用时引用计数变化

function refcountChange()
{
    $a = 'aa';
    $b = &$a; //a和b绑在一起,a变成啥b就变成啥。b变成啥a就变成啥
    $c = $b;
    $a = 'bb';
    echo $b.PHP_EOL;
    $b = 'cc';
    echo $a.PHP_EOL;

    xdebug_debug_zval('a');
    xdebug_debug_zval('b');
    xdebug_debug_zval('c');
    echo "脚本结束\n";
}

四 内存溢出

function oom()
{
while (1) {
    $arr[] = "dededededeeddddde";
}
}

五 内存泄漏

function xieLu()
{
    class A {
        public $b;
        public function __construct()
        {
            $this->a = str_repeat('A', 1024*1024);
        }
        public function setB(B $b)
        {
            $this->b = $b;
        }
    }
    class B
    {
        public $a;
        public function __construct()
        {
            $this->a = str_repeat('B', 1024*1024);
        }
        public function setA(A $a)
        {
            $this->a = $a;
        }
    }
    while (1) {
        $a = new A();
        $b = new B();
        $a->setB($b);
        $b->setA($a);
        unset($a);
        unset($b);
        echo memory_get_usage().PHP_EOL;
    }
}
在处理内存泄露时可以使用gc_collect_cycles()。

你可能感兴趣的:(php)