我有一个遍历数据库行的 do/while 循环。因为它在处理 100000 行时运行了很多天,所以内存消耗对于保持检查很重要,否则它会崩溃。现在每次迭代都会增加大约 4kb 的脚本内存使用量。我正在使用 memory_get_usage() 来监控使用情况。
我在每次迭代中首先取消设置循环中使用的每个变量,所以我真的不知道我还能做什么。我的猜测是 do/while 每次迭代都会收集一些数据,这就是消耗 4kb 内存的原因。我知道 4kb 听起来并不多,但当您有 100000 次迭代时,它很快就会开始增加。
有人可以建议另一种处理大量数据库行的方法或如何以某种方式消除这种“内存泄漏”吗?
编辑 这是 UPDATED 循环代码。在它上面只有几个 require_once()。
$URLs = new URLs_url(db());
$c = new Curl;
$c->headers = 1;
$c->timeout = 60;
$c->getinfo = true;
$c->follow = 0;
$c->save_cookies = false;
do {
// Get url that hasn't been checked for a week
$urls = null;
// Check week old
$urls = $URLs->all($where)->limit(10);
foreach($urls as $url) {
#echo date("d/m/Y h:i").' | Checking '.$url->url.' | db http_code: '.$url->http_code;
// Get http code
$c->url = $url->url;
$data = $c->get();
#echo ' - new http_code: '.$data['http_code'];
// Save info
$url->http_code = $data['http_code'];
$url->lastchecked = time();
$URLs->save($url);
$url = null;
#unset($c);
$data = null;
#echo "\n".memory_get_usage().' | ';
echo "\nInner loop memory usage: ".memory_get_usage();
}
echo "\nOuter loop memory usage: ".memory_get_usage();
} while($urls);
一些记录内存消耗在两个循环中的表现:
Inner loop memory usage: 611080
Inner loop memory usage: 612452
Inner loop memory usage: 613788
Inner loop memory usage: 615124
Inner loop memory usage: 616460
Inner loop memory usage: 617796
Inner loop memory usage: 619132
Inner loop memory usage: 620500
Inner loop memory usage: 621836
Inner loop memory usage: 623172
Outer loop memory usage: 545240
Inner loop memory usage: 630680
Inner loop memory usage: 632016
Inner loop memory usage: 633352
Inner loop memory usage: 634688
Inner loop memory usage: 636088
Inner loop memory usage: 637424
Inner loop memory usage: 638760
Inner loop memory usage: 640096
Inner loop memory usage: 641432
Inner loop memory usage: 642768
Outer loop memory usage: 556392
Inner loop memory usage: 640416
Inner loop memory usage: 641752
Inner loop memory usage: 643088
Inner loop memory usage: 644424
Inner loop memory usage: 645760
Inner loop memory usage: 647096
Inner loop memory usage: 648432
Inner loop memory usage: 649768
Inner loop memory usage: 651104
Inner loop memory usage: 652568
Outer loop memory usage: 567608
Inner loop memory usage: 645924
Inner loop memory usage: 647260
Inner loop memory usage: 648596
Inner loop memory usage: 649932
Inner loop memory usage: 651268
Inner loop memory usage: 652604
Inner loop memory usage: 653940
Inner loop memory usage: 655276
Inner loop memory usage: 656624
Inner loop memory usage: 657960
Outer loop memory usage: 578732
最佳答案
这个位应该只发生一次,在循环之前:
$c = new Curl;
$c->headers = 1;
$c->timeout = 60;
...
$c->getinfo = true;
$c->follow = 0;
$c->save_cookies = false;
编辑:哦,整个事情都包裹在一个 do/while 循环中。/捂脸
编辑 2:还有这个重要的一点:
unset($class_object) does not release resources allocated by the object. If used in loops, which create and destroy objects, that might easily lead to a resource problem. Explicitly call the destructor to circumvent the problem.
http://www.php.net/manual/en/function.unset.php#98692
编辑 3:
这是什么?不能以某种方式将其移出循环吗?
$URLs = new URLs_url(db());
编辑 4:
现在尝试删除这些行。
$url->http_code = $data['http_code'];
$url->lastchecked = time();
$URLs->save($url);
关于PHP & do/while 循环内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3210757/