即使未达到 memory_limit,PHP 内存不足错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13955914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:20:55  来源:igfitidea点击:

PHP out of memory error even though memory_limit not reached

memoryphpphp-ini

提问by user8109

I have just inherited a site with a PHP script that is consistently running out of memory at 117 MB. This happens even when I increase PHP's memory_limit variable to 312 MB, which I'm doing via php.ini.

我刚刚继承了一个带有 PHP 脚本的站点,该脚本始终以 117 MB 的速度耗尽内存。即使我通过 php.ini 将 PHP 的 memory_limit 变量增加到 312 MB,也会发生这种情况。

This is now solved thanks to a great clue from pcguru. See my answer below that begins: I have finally found the answer

由于 pcguru 提供了一个很好的线索,这个问题现在已经解决了。请参阅下面开始的我的答案:我终于找到了答案

ini_get('memory_limit')returns the value set in php.ini, so I'm certain Apache has restarted after changing the value. I'm using memory_get_usage(true)to return the memory consumed by the script at various points along the way. And it's consistently failing when it gets to 117 MB.

ini_get('memory_limit')返回在 php.ini 中设置的值,因此我确定更改该值后 Apache 已重新启动。我正在使用memory_get_usage(true)返回脚本在整个过程中的各个点消耗的内存。当它达到 117 MB 时,它一直失败。

Is there some internal PHP limit I'm unaware of that has it never allocate more than 117MB to an individual script?

是否有一些我不知道的内部 PHP 限制,它从未为单个脚本分配超过 117MB 的空间?

The server has 1GB of RAM and is running CentOS. I have root shell access. PHP is version 5.3.18. MySQL is version 5.1.66-cll.

服务器有 1GB 的 RAM 并运行 CentOS。我有 root shell 访问权限。PHP 是 5.3.18 版本。MySQL 是 5.1.66-cll 版本。

This script is behind a username/password and I can't provide public access to it.

此脚本位于用户名/密码后面,我无法提供对它的公开访问。

Edited to Add:

编辑添加:

1) Thanks all for your help to date. You'll find more info in my replies to specific user comments under various answers below.

1) 感谢大家迄今为止的帮助。您可以在我对特定用户评论的回复中找到更多信息,并在下面的各种答案下找到。

2) Suhosin is definitely not installed. I've checked in multiple places including running a script and check for constants and running php -v

2) Suhosin 肯定没有安装。我已经检查了多个地方,包括运行脚本和检查常量和运行 php -v

3) The apache log has no record of the specific error message I'm getting. Logging is switched on in php.ini. I piped through grep to search the entire log.

3) apache 日志没有记录我收到的特定错误消息。日志记录在 php.ini 中打开。我通过 grep 来搜索整个日志。

4) Is it possible the wrong error is being reported in this case?

4) 在这种情况下是否有可能报告错误的错误?

采纳答案by user8109

I have finally found the answer. The clue came from pcguru's answer beginning 'Since the server has only 1 GB of RAM...'.

我终于找到了答案。线索来自 pcguru 的回答,开头是“因为服务器只有 1 GB 的内存......”。

On a hunch I looked to see whether Apache had memory limits of its own as those were likely to affect PHP's ability to allocate memory. Right at the top of httpd.conf I found this statement: RLimitMEM 204535125

凭直觉,我想看看 Apache 是否有自己的内存限制,因为这些限制可能会影响 PHP 分配内存的能力。在 httpd.conf 的顶部,我发现了以下声明:RLimitMEM 204535125

This is put there by whm/cpanel. According to the following webpage whm/cpanel incorrectly calculates its value on a virtual server... http://forums.jaguarpc.com/vps-dedicated/17341-apache-memory-limit-rlimitmem.html

这是由 whm/cpanel 放在那里的。根据以下网页 whm/cpanel 在虚拟服务器上错误地计算其值... http://forums.jaguarpc.com/vps-dedicated/17341-apache-memory-limit-rlimitmem.html

The script that runs out of memory gets most of the way through, so I increased RLimitMEM to 268435456 (256 MB) and reran the script. It completed its array merge and produced the csv file for download.

内存不足的脚本大部分都通过了,所以我将 RLimitMEM 增加到 268435456 (256 MB) 并重新运行脚本。它完成了数组合并并生成了 csv 文件以供下载。

ETA: After further reading about RLimitMEM and RLimitCPU I decided to remove them from httpd.conf. This allows ini_set('memory_limit','###M') to work, and I now give that particular script the extra memory it needs. I also doubled the RAM on that server.

ETA:在进一步阅读 RLimitMEM 和 RLimitCPU 之后,我决定从 httpd.conf 中删除它们。这允许 ini_set('memory_limit','###M') 工作,我现在为该特定脚本提供它需要的额外内存。我还将该服务器上的 RAM 翻了一番。

Thank you to everyone for your help in detecting this rather thorny issue, and especially to pcguru who came up with the vital clue that got me to the solution.

感谢大家帮助检测这个相当棘手的问题,尤其是 pcguru,他提出了让我找到解决方案的重要线索。

回答by oldwizard

Since the server has only 1 GB of RAM I'm leaning towards the possibility that you have actually run out of system memory entirely.

由于服务器只有 1 GB 的 RAM,我倾向于您实际上已经完全耗尽系统内存的可能性。

See this thread. You get the same "PHP Fatal error: Out of memory" instead of the more common "Fatal error: Allowed memory size of ...". Your error indicates the system cannot allocate more memory at all, meaning even PHP:s internal functions cannot allocate more memory, let alone your own code.

看到这个线程。您会得到相同的“PHP 致命错误:内存不足”,而不是更常见的“致命错误:允许的内存大小为……”。您的错误表明系统根本无法分配更多内存,这意味着即使是 PHP:s 内部函数也无法分配更多内存,更不用说您自己的代码了。

How is PHP configured to run with Apache? As a module or as CGI? How many PHP processes can you have running at the same time? Do you have swap space available?

PHP 如何配置为与 Apache 一起运行?作为模块还是作为 CGI?您可以同时运行多少个 PHP 进程?你有可用的交换空间吗?

If you use PHP as a module in Apache, Apache has a nasty habit of keeping memory that the PHP process allocated. Guessing since it can't restart the PHP module in the worker, just restart the worker entirely. Each worker that has served PHP simply grows to the PHP memory limit over time as that worker serves a script that allocates a lot of RAM. So if you have many workers at the same time, each using 100 MB+, you will quickly run out of RAM. Try limiting the number of simultaneous workers in Apache.

如果您在 Apache 中使用 PHP 作为模块,Apache 有一个讨厌的习惯,即保留 PHP 进程分配的内存。猜测既然无法重启worker中的PHP模块,就完全重启worker即可。随着时间的推移,为 PHP 提供服务的每个 worker 只会增长到 PHP 内存限制,因为该 worker 提供了一个分配大量 RAM 的脚本。因此,如果您同时有许多工作人员,每个工作人员使用 100 MB+,您将很快耗尽 RAM。尝试限制 Apache 中并发工作人员的数量。

回答by aebersold

This may not be the answer to your problem, but if you run PHP from the command line you can overrite the memory limit from php.ini.

这可能不是您问题的答案,但如果您从命令行运行 PHP,您可以覆盖 php.ini 的内存限制。

php -d memory_limit=321M my_script.php

I'm not exactly sure what the default memory limit via cli is.

我不确定通过 cli 的默认内存限制是多少。

Also, you can run php --iniand check the results.

此外,您可以运行php --ini并检查结果。

回答by K.A.F.

This isn't an answer to why your script is dying after a certain memory usage, but you can get around it by removing the memory limit entirely within the PHP script itself:

这不是为什么您的脚本在一定内存使用后死亡的答案,但您可以通过完全在 PHP 脚本本身中删除内存限制来解决这个问题:

ini_set('memory_limit', '-1');

This is dangerous.If you have a runaway script, PHP will take memory until your server has none left to allocate and falls over. So you should only use this if you're surethe script itself isn't a problem, and only to test the output.

这是危险的。如果您有一个失控的脚本,PHP 将占用内存,直到您的服务器没有剩余的内存可以分配并发生故障。所以你应该只在你确定脚本本身没有问题时才使用它,并且只用于测试输出。

As to if PHP has some per-script limit on memory usage, no. I have personally run scripts with near 1GB memory usage.

至于 PHP 是否对每个脚本的内存使用有一些限制,没有。我亲自运行了接近 1GB 内存使用量的脚本。

回答by Peter Kiss

You have an infinite loop somewhere in your code.

您的代码中某处有一个无限循环。