记因PHP的内存溢出导致的事故之解决

如果对您有用记得关注,更多干货。

今天上午刚到公司,就有同事在公司群里反映某个计划任务出现问题了。我就怀着刨根问底的心,去查看了log。发现挺有意思的一个问题,PHP内存溢出导致脚本执行失败。那就一起来看个究竟吧!

  1. 首先查看了计划任务的Log

从报错信息字面意思可以看出,允许的134217728 bytes的内存已经用尽,还要试图分配12961640 bytes
内存。

给你(当前脚本)分配的内存你已经用完了,你还想问系统要内存。系统这时想对你说:

地主家也没有余粮啊(借用葛优大爷的一句话)

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

  1. 分析"事故"原因

    脚本一次性读取了大量的数据(可能是读的文件,可能是读取的数据库)

    如下图: 往杯子(分配给当前脚本的内存)里面倒数水(log文件的数据),杯子容量(内存)不够用

  2. 解决方案

    a. 既然杯子小 就换个大杯子(增大给脚本分配的内存)治标不治本: ini_set(‘memory_limit‘,‘100M‘);

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

看看结果

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

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

      (PHP变量底层实现是一个_zval_struct结构体,is_ref__gc表示引用计数 is_ref__gc表示是否为引用)

时间: 2024-10-14 05:39:50

记因PHP的内存溢出导致的事故之解决的相关文章

PHP内存溢出Allowed memory size of 解决办法

PHP内存溢出Allowed memory size of 解决办法 博客分类: php ============================Allowed memory size of  xxx bytes 以前追踪过这个问题,但是那个时候工具用的不太好,没看的这么细,这次搞的比较细,修正了偶以前的看法 .于是写小文一篇总结一下. PHP偶尔会爆一下如下 错误Allowed memory size of  xxx bytes exhausted at xxx:xxx (tried to a

jvm虚拟机(一):jvm内存溢出问题的分析与解决

??学习一下java虚拟机系列,之一 添加运行参数-XX:+HeapDumpOnOutOfMemoryError -Xms30m -Xmx30m -XX:+HeapDumpOnOutOfMemoryError 这个参数会生成堆栈快照,用于定位异常 模拟内存溢出的场景,简单代码: 123456789101112131415161718192021222324252627282930313233 package top.alertcode.demo.jvm; import java.util.Arr

记一次java内存溢出的解决过程

注:本文主要记录这次解决内存溢出问题的过程而不是具体问题. 最近在写一个搜索引擎,使用倒排索引结构进行文档检索,保存索引的基本思想是先将倒排列表保存到内存中一个有序Map里(TreeMap),然后当内存占用达到一定阈值的时候将内存中的倒排列表有序写入磁盘,当磁盘已经存在索引时,则将内存中的索引和磁盘中的索引进行合并,生成新的索引,合并过程类似于归并排序.合并内存索引和磁盘索引的代码如下: public synchronized void merge(){ LogUtil.info("Invert

ZABBIX:内存溢出导致zabbix-server/zabbix_server 服务启动不起来

30964:20180830:105530.520 Starting Zabbix Server. Zabbix 3.4.10 (revision 81503).30964:20180830:105530.520 ** Enabled features **30964:20180830:105530.520 SNMP monitoring: YES30964:20180830:105530.521 IPMI monitoring: YES30964:20180830:105530.521 Web

android解决内存溢出的问题(没有从根本上解决)

Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>

C#打开tif文件时内存溢出(System.OutOfMemoryException)解决办法

前言 原创性声明 此博文的出处 为http://blog.csdn.net/zhujunxxxxx/article/details/40649887如果进行转载请注明出处.本文作者原创,邮箱[email protected],如有问题请联系作者 我在做一个统计图片长和宽的软件时遇到一个问题,本来是用的 Image img = null; img = Image.FromFile(f.FullName); w = img.Width; h = img.Height; 这段代码来获取图片的长和宽的,

PHP内存溢出 Allowed memory size of 解决办法

PHP出现如下错误:Allowed memory size of  xxx bytes exhausted at xxx:xxx (tried to allocate xxx bytes)    关于这一点,本站点中,http://nodonkey.iteye.com/blog/728223 有所讲述.        同时,还有 http://hi.baidu.com/thinkinginlamp/blog/item/e400f819a3caab7cdbb4bd4e.html 此文也是讲这个问题

eclipse中启动项目报内存溢出问题通过修改配置解决

先停止运行,双击图片中的指定位置,显示具体配置页面. 点击图片中链接 在“arguments”标签卡中对“VM arguments”进行配置,在第一行添加 -Xms256M -Xmx1024M -XX:PermSize=64M -XX:MaxPermSize=128M 点击“apply”按钮.Tomcat停止运行才可以修改.

记一次内存溢出的分析经历

背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的通信框架使用的是thrift. thrift很多优点就不多说了,它是facebook的开源的rpc框架,主要是它能够跨语言,序列化速度快,但是他有个不讨喜的地方就是它必须用自己IDL来定义接口 thrift版本:0.9.2. 问题定位与分析 步骤一.初步分析 客户端无法连接服务端,查看服务器的端口开