为了账号安全,请及时绑定邮箱和手机立即绑定

PHP - 在生产服务器上随机触发内存耗尽错误

PHP - 在生产服务器上随机触发内存耗尽错误

PHP
慕运维8079593 2022-07-29 15:16:54
我随机(每天大约 20 次)在生产服务器(PHP 7.0.32)上收到此错误:PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 4787537204 bytes)到目前为止,错误的“存在”相当低,但是因为我不确定出了什么问题,所以我担心未来和更大的问题。发生错误时,我在页面顶部运行此代码:    $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;我无法重现开发服务器的问题,我不确定是什么原因造成的以及如何调试(我无法在生产服务器上启用调试功能)。在致命错误之前没有其他警告或通知。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"        }]}
查看完整描述

3 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

这是我能想到的唯一合理的解释,请检查我的推论是否属实。


您$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

您将不得不挖掘代码的其他部分,以了解为什么会出现这种情况


查看完整回答
反对 回复 2022-07-29
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

在摸索了一下之后(请参阅从完全不同的切线开始的其他答案),似乎超过 4 GB RAM 的巨大内存分配发生在strtotime. 目前尚不清楚这是否与 PHP 错误 #53502(一个旧的 PHP 5.3 错误,当前标记为已关闭)有关。

然而,改变

$end[$id] = ($endDate !== "") ? strtotime($endDate." UTC") : $curTime;

date_default_timezone_set("UTC");
$end[$id] = ($endDate !== "") ? strtotime($endDate) : $curTime;

摆脱现象,运行平稳。目前尚不清楚是否有任何特定值$endDate导致了这种情况,或者还有什么可能是促成因素。


查看完整回答
反对 回复 2022-07-29
?
米脂

TA贡献1836条经验 获得超3个赞

您可能希望将其添加到您的脚本中(放在最上面)

 ini_set('memory_limit', '-1');

您可以稍后设置-1为“256如果有64”或“更少”,这还不够。


查看完整回答
反对 回复 2022-07-29
  • 3 回答
  • 0 关注
  • 101 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信