PHP 7.2.9 在随机时间内存不足

Posted

技术标签:

【中文标题】PHP 7.2.9 在随机时间内存不足【英文标题】:PHP 7.2.9 out of memory at random times 【发布时间】:2018-10-16 09:28:58 【问题描述】:

我们在 Windows 上将 Apache(32 位)与 php 7.2.9 结合使用。它大部分时间都有效,但经过大量刷新(每次重新启动 apache 时都是随机次数),我们收到此错误:致命错误:内存不足(分配 27262976)试图在 [random] 中分配 4096 个字节文件,总是一个不同的]在第 x 行。

奇怪的是它一直给出完全相同的错误,直到我们重新启动 Apache,然后它工作了几个小时。

同样奇怪的是,我们在 php.ini 中设置了 512M 作为内存限制,但它说分配了 27262976,即(正好)26MB。我们有 2GB+ RAM 可用,所以这不是问题。

如果有人知道如何解决这个问题,那就太好了。

谢谢, 拉尔斯

【问题讨论】:

第一步 - 在新的浏览器选项卡中运行新文件 (phpinfo.php) 中的 phpinfo,查看正在加载的 php.ini 以及每个选项设置的值。第二步 - 你没有释放内存,我猜一个大脚本已经到位并且相当耗费资源,这占用了你所有的内存。大量执行这些脚本 = 内存增加 = 泄漏。 您是否有任何未正确终止的延迟或长时间运行的进程? 你有内存泄漏。确保关闭脚本并释放资源(例如打开的数据库连接/文件)。还要确保您的 GarbageCollector 正常工作。 同意以上所有。使用unset() 指导 GC 以更好地管理资源。您也可以尝试调用memory_get_usage() 来检查内存使用情况。通常只是逐步调试以查找泄漏 不要忘记 memory_limit 指的是 EACH 和 EVERY 脚本,因此如果您有 5 个同时连接并且其中 4 个分配每个 400 MB - 那么第五个可能无法分配您的服务器上的相同数量(2GB RAM) 【参考方案1】:

很可能内存只是变得支离破碎。 (我之前有过similar issues。)您必须在代码运行时让垃圾收集更多地工作。

一种方法

您必须确定整个过程中创建最大数组或对象的部分,并将其拆分为多个较小的步骤。我不知道您的代码做了什么,但重要的部分是 PHP 在某些步骤进行垃圾收集,例如当函数返回并释放自己的环境时。因此,假设您在一个循环中处理 10000 个文件,那么实现一个队列系统会很有帮助,您可以在其中放入 100 个文件,调用一个函数来处理它们,然后继续处理队列。听起来很傻,我知道,但如果你仔细想想,这很有意义。

另一种方式

您可以为可变长度数据分配相同大小的结构,例如仅部分使用的 50-100k 块;这样内存就不会变得碎片化。但是垃圾收集要好得多,这通常是他的工作。

不得已

当你的内存大约用完一半时——你可以通过调用 memory_get_usage(true) 来检查——序列化你正在使用的大结构,取消设置变量,然后取消序列化它。这应该可以解决分配问题。

希望以上内容有所帮助。

【讨论】:

以上是关于PHP 7.2.9 在随机时间内存不足的主要内容,如果未能解决你的问题,请参考以下文章

构建树时PHP致命错误内存不足

Composer 要求内存不足。 PHP 致命错误:允许的内存大小为 1610612736 字节已用完 Voyager

在 PHP 中执行大型 SQL 查询字符串时出现“内存不足”错误

Composer 内存不足 - 需要其他方法来增加 PHP memory_limit

即使更新了 php.ini 也内存不足

Composer 要求内存不足。 PHP致命错误:允许的内存大小为1610612736字节已用尽