我在生产服务器 (PHP 7.0.32) 上随机(大约每天 20 次)收到此错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4787537204 bytes)
到目前为止,错误的“存在率”相当低,但因为我不确定出了什么问题,所以我担心 future 和更大的问题。
当错误发生时,我在页面顶部运行此代码:
$curTime = time();
$dataIds = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
$end = array();
$update = array();
$dbUpdate = array();
foreach($dataIds as $id) {
$f = fopen( "./data/{$id}.json", "r");
if ($f === false) {
continue;
}
$data = fread($f, 1024);
fclose($f);
$data = json_decode($data, true);
if (!isset($data['input'])) {
continue;
}
$endDate = $data['input'][0]['end'];
$updateDate = $data['input'][0]['start'];
$dbUpdateDate = $data['input'][0]['update'];
$end[$id] = ($endDate !== "") ? strtotime($endDate." UTC") : $curTime;
$update[$id] = ($updateDate !== "") ? strtotime($updateDate." UTC") : $curTime;
$dbUpdate[$id] = ($dbUpdateDate !== "") ? strtotime($dbUpdateDate." UTC") : $curTime;
}
这一行触发了错误:
$end[$id] = ($endDate !== "") ? strtotime($endDate." UTC") : $curTime;
我无法在开发服务器上重现问题,并且不确定是什么原因导致此问题以及如何调试此问题(我无法在生产服务器上启用调试功能)。在发生 fatal error 之前没有其他警告或通知。
json数据文件很小,大约500字节。然而,它们是通过 cron 作业更新的。所以理论上我可以打开不完整的文件。但在这种情况下,正如我测试的那样,json_decode
返回 null
。
json 示例:
{
"input": [{
"id": "1",
"start": "2019-11-15 06:00:00",
"end": "2019-11-18 12:00:00",
"update": "2019-11-15 10:52:44"
}]
}
最佳答案
这是我能想到的唯一合理的解释,请检查我的推论是否属实。
您的$dataIds
不是小整数,而是实际代码中的数十亿。由于某种原因,PHP 似乎将 $this->end
键入为字符串而不是数组。实际上,您正在这样做:
$stuff='string';
$stuff[5000000000]='y'; // will allocate 5 GB of RAM, exceeding your 128M maximum
当您认为您正在这样做时:
$stuff=new Array();
$stuff[5000000000]='y'; // will allocate just a few Bytes since it is an asssociative Array
您必须深入研究代码的其他部分才能了解为什么会出现这种情况
关于PHP - 在生产服务器上随机触发内存耗尽错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59883427/