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

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

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

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

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

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

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

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

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

  1. 模拟一下"案发现场"

  • 新建一个mem_exhausted.php文件 copy过来一个2.4M的log文件做测试用

  • 写个简单的脚本重现"案发现场" 故意分配1M的内存 来读取2.4M的log

  • 执行脚本,"案发现场"重现

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

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

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

  1. 分析"事故"原因

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

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

  2. 解决方案

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

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

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

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

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

看看结果

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

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

  1. 其他优化方案

    • 应当尽可能减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。

    • 数据库操作完成后,要马上关闭连接;

    • 一个对象使用完,要及时调用析构函数(__destruct())

    • 用过的变量及时销毁(unset())掉

    • 可以使用memory_get_usage()函数,获取当前占用内存 根据当前使用的内存来调整程序

    • unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。(PHP内核的gc垃圾回收机制决定)

    • 有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存

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

出处:https://www.cnblogs.com/gaohj/p/6727069.html?utm_source=tuicool&utm_medium=referral

### 回答1: PHP内存溢出可以通过以下几种方法进行优化: 1. 优化代码:检查代码是否存在内存泄漏、循环引用等问题,可以使用 PHP 内置的工具 xdebug 进行分析定位问题。 2. 增加内存限制:可以通过修改 PHP 配置文件中的 memory_limit 参数来增加 PHP 的可用内存。但是要注意,增加内存限制可能会导致其他性能问题,因此应该谨慎使用。 3. 减少内存使用:可以通过减少变量使用、使用更高效的算法、避免多次查询数据库等方法来减少 PHP内存使用。 4. 使用缓存:可以使用缓存来避免频繁的查询数据库和计算操作,从而减少 PHP内存使用。 5. 升级硬件:如果以上方法无法解决问题,可以考虑升级服务器硬件,增加可用内存和 CPU 资源。 ### 回答2: PHP内存溢出是指在PHP程序运行过程中,分配给程序的内存不足以满足程序的内存需求,导致程序无法正常执行或崩溃的现象。下面是一些优化策略来解决PHP内存溢出问题: 1. 优化算法和逻辑:检查程序逻辑,确保使用最佳的算法和避免不必要的内存分配。减少循环嵌套、递归调用和无尽的迭代。 2. 减少数据量和处理:通过限制查询结果集的大小、分批进行处理或跳过不必要的数据,减少内存的使用。可以使用数据库的分页查询、缓存机制或延迟加载等技术。 3. 释放不再使用的内存:在程序执行过程中,及时释放不再使用的变量、对象和资源。 4. 调整PHP配置:增加PHP的最大内存限制(memory_limit),可以通过编辑php.ini文件或在代码中使用ini_set函数进行设置。 5. 使用合适的数据结构和缓存:根据具体需求,选择合适的数据结构和缓存机制来优化内存使用。例如,使用数组代替对象、使用缓存技术避免重复计算等。 6. 优化第三方库和模块:检查使用的第三方库或模块是否存在内存泄漏或内存占用过高的问题,可以尝试更新版本或寻找替代方案。 7. 分析和调试工具:使用内存分析工具,如Xdebug、Zend Debugger等,来定位和解决内存溢出问题。 总之,优化PHP内存溢出问题需要综合考虑程序逻辑、数据处理、PHP配置、数据结构和缓存等多个方面,根据具体情况采取相应的优化措施,以提高程序的性能和稳定性。 ### 回答3: 在PHP中,处理大量数据或使用大内存的程序可能会导致内存溢出。以下是一些优化技巧来减少PHP内存溢出的可能性: 1. 优化代码逻辑:检查代码中是否有无限循环、递归调用等因素可能导致内存溢出的问题,并进行修复。 2. 减少内存占用:尽量使用更少的内存来执行操作。例如,使用迭代而不是递归来处理大量数据,避免一次性加载大量数据到内存中。 3. 使用适当的数据结构:选择适当的数据结构以减少内存的使用。例如,使用生成器(Generator)来逐行处理大文件,而不是一次性将整个文件加载到内存中。 4. 及时释放内存:在处理大量数据时,及时释放不再需要的变量、对象等资源,可以使用unset()函数来释放变量所占用的内存。 5. 调整PHP配置参数:调整PHP内存限制参数(如memory_limit)为合适的值,确保分配足够的内存来处理大数据操作。 6. 使用缓存:利用缓存系统(如Memcached、Redis等),将一些常用的数据缓存起来,减少频繁读取数据库或计算过程。 7. 使用分页或分块处理:如果可能,将大规模数据的操作分页或分块处理,减少一次性处理大量数据的压力。 8. 升级硬件:如果以上优化仍然无法解决内存溢出的问题,可以考虑升级服务器硬件,增加可用的内存容量。 重要注意事项:在进行内存优化时,应该进行充分的测试和排查,以确保不会影响系统的正常运行和各种边界情况的处理。同时,可以使用内存分析工具来帮助定位和解决内存溢出问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值