23

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

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

ini_get('memory_limit')返回在 php.ini 中设置的值,所以我确定 Apache 在更改值后已经重新启动。我memory_get_usage(true)用来返回脚本在沿途各个点消耗的内存。当它达到 117 MB 时,它一直在失败。

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

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

该脚本位于用户名/密码后面,我无法提供对其的公共访问权限。

编辑添加:

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

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

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

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

4

5 回答 5

21

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

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

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

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

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

感谢大家帮助发现这个相当棘手的问题,特别是 pcguru 提出了让我找到解决方案的重要线索。

于 2012-12-20T07:53:04.993 回答
9

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

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

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

如果您在 Apache 中使用 PHP 作为模块,Apache 有一个讨厌的习惯,即保留 PHP 进程分配的内存。猜测由于它无法重新启动worker中的PHP模块,所以只需完全重新启动worker。随着时间的推移,每个为 PHP 提供服务的工作人员都会简单地增长到 PHP 内存限制,因为该工作人员服务于一个分配大量 RAM 的脚本。因此,如果您同时有许多工作人员,每个工作人员使用 100 MB 以上,您将很快耗尽 RAM。尝试限制 Apache 中同时工作的人数。

于 2012-12-19T20:58:51.563 回答
3

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

php -d memory_limit=321M my_script.php

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

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

于 2012-12-19T15:52:45.160 回答
2

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

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

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

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

于 2012-12-19T16:31:23.257 回答
-5

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

于 2012-12-19T16:09:39.470 回答