设为首页 收藏本站
查看: 885|回复: 0

[经验分享] 记因PHP的内存溢出导致的事故之解决

[复制链接]

尚未签到

发表于 2017-12-30 16:34:10 | 显示全部楼层 |阅读模式
  如果对您有用记得关注,更多干货。
  今天上午刚到公司,就有同事在公司群里反映某个计划任务出现问题了。我就怀着刨根问底的心,去查看了log。发现挺有意思的一个问题,PHP内存溢出导致脚本执行失败。那就一起来看个究竟吧!

  •   首先查看了计划任务的Log
DSC0000.jpg

  从报错信息字面意思可以看出,允许的134217728 bytes的内存已经用尽,还要试图分配12961640 bytes
  内存。
  给你(当前脚本)分配的内存你已经用完了,你还想问系统要内存。系统这时想对你说:
  地主家也没有余粮啊(借用葛优大爷的一句话)
DSC0001.jpg


  •   模拟一下"案发现场"


  •   新建一个mem_exhausted.php文件 copy过来一个2.4M的log文件做测试用
  •   写个简单的脚本重现"案发现场" 故意分配1M的内存 来读取2.4M的log
  •   执行脚本,"案发现场"重现
DSC0002.jpg

DSC0003.jpg

DSC0004.jpg


  •   分析"事故"原因
      脚本一次性读取了大量的数据(可能是读的文件,可能是读取的数据库)
      如下图: 往杯子(分配给当前脚本的内存)里面倒数水(log文件的数据),杯子容量(内存)不够用
  •   解决方案
      a. 既然杯子小 就换个大杯子(增大给脚本分配的内存)治标不治本: ini_set('memory_limit','100M');
DSC0005.jpg

DSC0006.jpg

  b. 把水分批次倒入杯子中(循环,分段读取数据,读数据库的话可以用limit)
DSC0007.jpg

  看看结果
DSC0008.jpg

  分段读取也是可以解决问题滴

  •   其他优化方案



    •   应当尽可能减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。
    •   数据库操作完成后,要马上关闭连接;
    •   一个对象使用完,要及时调用析构函数(__destruct())
    •   用过的变量及时销毁(unset())掉
    •   可以使用memory_get_usage()函数,获取当前占用内存 根据当前使用的内存来调整程序
    •   unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。(PHP内核的gc垃圾回收机制决定)
    •   有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存
        (PHP变量底层实现是一个_zval_struct结构体,is_ref__gc表示引用计数 is_ref__gc表示是否为引用)


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-429724-1-1.html 上篇帖子: 理清PHP在Linxu下执行时的文件权限 下篇帖子: 优化php代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表