我遇到了可怕的错误消息,可能通过艰苦的努力,PHP内存不足:
在第123行的file.php中,####字节的允许内存大小耗尽(尝试分配####字节)
如果您知道自己在做什么并希望增加限制,请参阅memory_limit:
ini_set('memory_limit', '16M');
ini_set('memory_limit', -1); // no limit
Run Code Online (Sandbox Code Playgroud)
谨防!你可能只是解决症状而不是问题!
错误消息指向一条带有循环的行,我认为该循环正在泄漏或不必要地累积内存.我memory_get_usage()在每次迭代结束时打印语句,可以看到数字慢慢增长,直到达到极限:
foreach ($users as $user) {
$task = new Task;
$task->run($user);
unset($task); // Free the variable in an attempt to recover memory
print memory_get_usage(true); // increases over time
}
Run Code Online (Sandbox Code Playgroud)
对于这个问题的目的,让我们假设最坏的面条代码可以想象在全球范围内的某处藏匿在$user或Task.
什么工具,PHP技巧或调试巫毒可以帮助我找到并解决问题?
我发布这个以防万一其他人正在寻找相同的解决方案,因为我只是在这个废话上浪费了两天.
我有一个cron作业,使用以下代码每天使用一个非常大的文件更新数据库:
if (($handle = fopen(dirname(__FILE__) . '/uncompressed', "r")) !== FALSE)
{
while (($data = fgets($handle)) !== FALSE)
{
$thisline = json_decode($data, true);
$this->regen($thisline);
}
fclose($handle);
}
Run Code Online (Sandbox Code Playgroud)
这是一个仅用于cron作业的Codeigniter控制器.$ this-> regen函数运行一系列不同的检查,并存储数据库中该行的正确信息.该文件本身是由换行符分隔的超过300MB的JSON.
问题是:在整个内存耗尽之前,它只会处理大约20,000行.