PHP失败了内存不足:杀死进程 - 我可以使循环更有效吗?

时间:2017-03-17 21:27:26

标签: php linux-kernel

我的php内存不足,出现服务器错误“内存不足:杀死进程......大约25%的过程”虽然它搜索了大约10,000行,但符合条件的行数,因此需要在进程结束时存储并写入文件,小于200.所以我不确定为什么内存不足。

我收到此错误是因为我没有在每次循环后清除变量,还是需要增加服务器上的内存?

简要的过程是:   - LOOPA - 循环遍历400个邮政编码列表   - 为每个拉链使用一个api调用 - 获取每个拉链内所有位置的列表(通常约为40-50)

- SUBLOOP1 - 对于找到的每个地方,使用api调用来获取该地点的所有活动

---- SUBLOOP1A循环事件以计算每个地方的数量

zips = file($configFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$dnis = file($dniFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$s3->registerStreamWrapper();
$file = fopen("s3://{$bucket}/{$key}", 'w') or die("Unable to open file!");
fwrite($file, $type . " id" . "\t" . $type . " name" . "\t" . "zip" . "\t" . "event count" . "\n" );

foreach($zips as $n => $zip){
    //first line is the lable to describe zips, so skip it
    if ($n < 1) continue;
    $params = $url;
    $params .= "&q=" . $zip;

    $more_node_pages = true;
    while ($more_node_pages){
    $res = fetchEvents($params);

        //Now find the number of events for each place
        foreach($res->data as $node){
            //first check if on Do Not Include list
            $countevents = true;
            foreach($dnis as $dni) {
                if ($dni == $node->id) {
                    echo "Not going to get events for ". $node->name . "   id# " . $dni . "\n\n";
                    $countevents = false;
                    break;
                }
            }
            //if it found a match, skip this and go to the next
            if (!$countevents) continue;
            $params = $url . $node->id . "/events/?fields=start_time.order(reverse_chronological)&limit=" . $limit . "&access_token=". $access_token; 

            //Count the number of valid upcoming events for that node
            $event_count = 0;
            $more_pages = true;
            $more_events = true;

            while ($more_pages) {

                $evResponse = fetchEvents($params);
                if (!empty($evResponse->error)) {
                    checkError($evResponse->error->message, $evResponse->error->code, $file);
                } 

                //if it finds any events for that place, go throught each event for that place one by one to count until you reach today
                foreach($evResponse->data as $event){
                    if(strtotime($event->start_time) > strtotime('now')){
                        $event_count++;
                    }
                    //else we have reached today's events for this node, so get out of this loop, and don't retrieve any more events for this node
                    else {
                        $more_events = false;
                        break;
                    }
                }

                if (!empty($evResponse->paging->next) and $more_events) $params = $evResponse->paging->next;
                else $more_pages = false;
            } //end while loop looking for more pages with more events for that node (page)

            if ($event_count > "0") {
                fwrite($file, $node->id . "\t" . $node->name . "\t" . $zip . "\t" . $event_count . "\n");
                echo $event_count . "\n";
            }
        } // loop back to the next place until done
        //test to see if there is an additional page
        if (!empty($res->paging->next)) $params = $res->paging->next; else $more_node_pages = false;
    } //close while loop for $more_node_pages containing additional nodes for that zip
} // loop back to the next zip until done
fclose($file);

2 个答案:

答案 0 :(得分:1)

我强烈建议在每个嵌套循环的开头添加输出。我认为你很可能有一个无限循环,导致脚本耗尽内存。

如果不是这种情况,那么您可以尝试通过将这行PHP添加到脚本顶部来增加PHP脚本的内存限制:

ini_set("memory_limit", "5G");

如果你的脚本需要超过5GB的RAM来处理400个邮政编码,我建议你打破你的脚本,这样你就可以运行0-10码,然后是11-20码,然后是21-30码等。

希望这会有所帮助,欢呼。

答案 1 :(得分:1)

你需要找出内存丢失的地方,然后你可以照顾它或解决它。 memory_get_usage()是你的朋友 - 在每个循环的顶部(或底部)打印一个标识符,这样你就可以看到&amp;在哪里耗尽记忆。