PHP运行出现FatalerrorAllowedmemo
搞PHP或者做运维的,跑脚本、导数据时碰上内存超限的Fatal error太常见了,白屏或者命令行直接挂掉,急得人抓瞎。这篇整理了一下实际排查时的思路,还有日常容易掉进去的坑,希望能少走点冤枉路。
干PHP开发的,或者平时管服务器的,谁还没被Fatal error Allowed memory size exhausted折腾过啊?定时任务正跑着导一批数据、处理几张高清图、或者刚把新代码扔上线,页面直接白屏,命令行也嘎嘣停了,就甩这么一句报错。进度卡在那儿,配置调来调去好像也没啥用,真挺恼火的。今天就把这种内存超限的排查路数和踩过的坑聊一下。
报错排查步骤
别一看到这种错就冲进php.ini里猛拉memory_limit,真不一定就是给的内存小了,不少时候其实是代码里头藏着事儿。先想想报错是在什么场景下弹出来的,如果只有批量导入、大文件处理这些重活才崩,那先估一下正常业务大概要多少内存。比如导入十万条普通结构的数据,256M一般都够跑了,结果你设到512M还叫唤内存不够,那直接去看代码里有没有死循环、是不是一口气把整批数据全装进内存了、大变量用完也没清理掉。
要是没干啥特殊操作,所有页面都时不时随机蹦这个错,就往回倒一倒:最近有没有装新扩展、是不是刚上线了新代码、PHP版本升没升过?排查的时候可以在代码关键地方用memory_get_usage()打个点,看看内存消耗在哪一步突然窜上去。经常掉进去的坑就是循环里一直拼那种超大的字符串、SQL查数据不写limit直接把整个表拉出来、递归忘了设出口无限往下套娃。
如果一圈查下来,确实是业务正常就得吃那么大内存,那再去调memory_limit也不迟。不过这里得留神,php-fpm和命令行CLI走的是两套不同的php.ini文件,别改错了地方,搞半天配置不生效还自己纳闷儿。