2

我有一个像这样的爬虫功能:

function crawl_page($url) {
    static $j;
    echo "recur no:".++$j."\n";
    static $seen = array();

    if (isset($seen[$url]) ) {
        return;
    }

    $seen[$url] = true;

    // some more code


   foreach($links as $link) {
               $link .= '?start='.rand(1,300)*50; 
               crawl_page($link );
   }
   unset($links);

}

该脚本在控制台本地运行。里面的静态数组可以很大,有几千个元素,还是内存中的数据还是一样的,还是每次新的递归调用完成的时候都复制了?经过 2000 或 3000 次重复后,php 进程太大了,内存超过 1 GB,最后崩溃。似乎每个递归都使用了过多的内存。是什么原因?

4

2 回答 2

0

这部分代码我有点疑惑:

 $link .= '?start='.rand(1,300)*50; 

这将制作每个链接的多个版本。如果其中一个页面使用它自己的链接来建立指向自身的链接,那么您自己就会陷入无限循环:

$link == '/', result: self: '/', crawl_page('/?start=50');
$link == '/?start=50', self: '/?start=50', result: crawl_page('/?start=50?start=200');
...

也可能是页面数乘以两次命中 0 到 299 之间的一个数字的平均值会因数组中的元素过多而耗尽内存。

于 2013-07-25T22:13:24.840 回答
0

使用简单的脚本进行测试

function func($iteration = 0) {
        if ($iteration++ == 3) return;
        print "\n$iteration\n";
        var_dump(memory_get_usage());
        static $var = array();
        var_dump(memory_get_usage());
        $var[] = str_repeat("byte", 100000);
        var_dump(memory_get_usage());
        func($iteration);
}

func();

给出:

1
int(632976)
int(632976)
int(1033232)

2
int(1033312)
int(1033312)
int(1433568)

3
int(1433648)
int(1433648)
int(1833904)

所以,我们看到了什么:内存使用量只在插入时有所不同,但使用static $var;并没有真正对内存产生很大的影响。

结论

它必须只是您的数组大小,临时结果等让您的内存超出,但静态数组只消耗一次内存(=它不会在每个函数调用中复制)。

于 2013-07-25T20:59:49.857 回答