PHP Fatal error: Allowed memory size of bytes exhausted

赞赏 2016-01-21

在导出订单数据的时候,当订单量达到13849的时候,页面就直接返回:500了。
查看nginx日志,错误信息如下:
[error] 6278#0: *33631288 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1048560 bytes)


优化方法

从nginx日志中可知,是内存不够用了。默认一个php进程允许占用的内存是134217728bytes,而这个php进程还需要1048560bytes内存才能往下执行。


在php.ini中有关于内存的限制:

memory_limit = 128M  //128M=131072K=134217728b

我可以把这个值改的大一点来解决问题。但不能每次都靠改大来解决。


通过用方法 memory_get_usage()逐行看程序内存占用,以此来优化内存。


1:去掉多余函数和变量 

代码中的空格和注释都不影响内存的占用,但调用文件中多余的函数和变量就会占用内存,于是把不用的函数和变量删除掉


2:不要声明多余的变量 

比如: 

把 $rs = round ( abs ( $a_dt - $b_dt ) / 86400 ); return $rs; 

改成 return round ( abs ( $a_dt - $b_dt ) / 86400 );


3:不用的变量及时释放掉

4:优化函数返回结果大小 函数尽可能的只返回每次调用所需要的结果集 

比如:要得到的是:$datastruct


5:优化mysql返回结果集的大小(这个是我这里面影响最大的) 

查询了一下表中数据的大小 

mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='flow' and table_name = 'channel_order_log_201511'; 

2.52MB. 

再看看结果集在PHP中占的内存: 

内存耗用:(76201912-1086264)/1024/1024 = 71.64M  

哇 PHP的数组太占内存了,网上有人做过数组占用内存的测试,如下图:

那么我们这么优化那?

  1. 缩小返回的结果集,一开始是查询出了所有字段,改成 只返回需要的字段 

  2. 2:在1的基础上,我们再使用 mysql_unbuffered_query来查询数据     

mysql_unbuffered_query()向MySQL发送一条SQL查询query,但不像mysql_query()那样自动获取并缓存结果集。一方面,这在处理很大的结果集时会节省可观的内存。另一方面,可以在获取第一行后立即对结果集进行操作,而不用等到整个SQL语句都执行完毕。  


PDO_Mysql也提供了这种使用方法:就是在prepare()方法之前增加: 

$conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);


登陆后阅读全文
阅读 3233 赞赏 0 有用 8 没用 0 收藏 0 分享

注意事项

mysql_unbuffered_query()的好处是有代价的: 在mysql_unbuffered_query()返回的结果集之上不能使用mysql_num_rows()和mysql_data_seek(),此外在向MySQL发送一条新的SQL查询之前,必须提取所有未缓存的SQL查询所产生的结果行。

PHP中的数组是用一种HASH结构(HashTable)来实现的, 关于PHP中的数组的实现,鸟哥有一篇文章介绍过:深入理解PHP之数组(遍历顺序) (http://www.laruence.com/2009/08/23/1065.html)

   


作者声明:本篇文章系本人原创,欢迎分享,但未经许可,谢绝转载。

0 条留言

赛蓝翔的头像

赛蓝翔

PHP开发一枚

相关文章

Linux php-fpm报错:allow_call_time_pass_reference

Ubuntu安装MySQL提示Depends: mysql-server-5.5 but it is not going

Linux下如何查看Nginx Apache MySQL PHP 的编译参数?

如何配置php显示错误信息?

6款程序员必备的开源中文汉字拼音转换及处理工具 (PHP Java .net)

mysql-bin.00000* 文件误删删除导致mysql启动不起来

Linux screen 提示:There is no screen to be resumed matching

Linux 服务器如何隐藏 PHP 版本号?

PHP 程序无法识别短标签

改了php.ini中的open_basedir仍报错open_basedir restriction in effect

有料推荐

这世界欠我一个这样的老公!

高校学生模仿“世界名画”摆拍,可以说是戏精本精了

iPhone X 跌破发行价,苏宁200亿入股恒大 | 财经日日评

果然是高手!这次在日本,特朗普竹杠敲得不是一般狠

资深黄牛现身说法:iPhone X价格秒变不停,就像炒股一样

长一样的双胞胎也能识别?蚂蚁金服发布「眼纹识别」技术

苏联是怎么被阿富汗拖垮的?

美团或入局「分时租赁」共享汽车,王兴要大笔投入「泛出行」领域了? | 36氪独家

你或许被“一盘番茄炒蛋”刷屏了,但有人辛酸,有人质疑

iPhone X发售前夜,黄牛与苹果公司的不安

他的文章

微信跳一跳刷分攻略

改了php.ini中的open_basedir仍报错open_basedir restriction in effect

推荐 | PHP WEB消息推送框架 web-msg-sender (PHPSocket.IO)

如何准确判断请求是不是搜索引擎爬虫(蜘蛛)发出的请求?(php window linux)

PHP Warning: feof() expects parameter 1 to be resource, null

php Warning: A non-numeric value encountered in

原来这条命令可以让我们快速找到php.ini的位置

换成https后,网站还是没有安全标志或安全小锁?

在百度站长平台如何将http换成https

php file_get_contents() 如何伪造发送 referer?

手机扫一扫
分享文章