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

标签 php memory

我在生产服务器 (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/

相关文章:

php - 使用 LAN 上不同 PC 上的同一个本地 MySQL 数据库

php - 仅使用 javascript 生成和保存/下载文件

java - Apache2 和 PHPJAVA 桥

c++ - 关于CUDA中的固定内存,它有上限吗?

C - 每次循环执行时,在循环中声明的变量是否在同一位置获取内存?

php - 如何一次更改所有学生的年级

php - 基于两个 mysql 字段进行计算

c - 为什么在 C 中不能使用 [] 为字符串分配内存?

c - 在内核中查找未知类型内存的大小

C++内存泄漏与否