我有一堆客户销售点(POS)系统,它定期将新的销售数据发送到一个集中数据库,该数据库将数据存储到一个大数据库中以生成报告 .
客户端POS基于PHPPOS,我实现了一个使用标准XML-RPC库将销售数据发送到服务的模块 . 服务器系统构建在CodeIgniter上,并使用XML-RPC和XML-RPCS库作为Web服务组件 . 每当我发送大量销售数据(销售表中只有50行,以及sales_items中与销售中每个项目相关的各行)时,我会收到以下错误:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M是 php.ini
中的默认值,但我认为这是一个很大的数字 . 事实上,我甚至尝试将此值设置为1024M,而它所做的只是需要更长的时间才能出错 .
至于我采取的步骤,我已经尝试禁用服务器端的所有处理,并且已经操纵它以返回固定响应而不管输入如何 . 但是,我认为问题在于实际发送数据 . 我甚至尝试禁用PHP的最大脚本执行时间,但仍然出错 .
23 回答
当你看到上面的错误 - 特别是如果
(tried to allocate __ bytes)
是一个低值,那可能是一个指标无限循环,就像一个无法自我调用的函数:ini_set('memory_limit', '-1');
会覆盖默认值PHP memory limit .PHP的内存分配可以永久调整,也可以暂时调整 .
永久
您可以通过两种方式永久更改PHP内存分配 .
如果您有权访问
php.ini
文件,则可以将memory_limit
的值编辑为您想要的值 .如果您无权访问
php.ini
文件(并且您的webhost允许),则可以通过.htaccess
文件覆盖内存分配 . 添加php_value memory_limit 128M
(或任何您想要的分配) .临时
您可以在PHP文件中动态调整内存分配 . 你只需要代码
ini_set('memory_limit', '128M');
(或任何你想要的分配) . 您可以通过将值设置为"-1"来删除内存限制(尽管可能仍适用机器或实例限制) .通过
ini_set('memory_limit', '-1');
更改memory_limit
是 not 一个合适的解决方案 . 请不要那样做 .您的PHP代码可能在某处出现内存泄漏,并且您告诉服务器只使用它想要的所有内存 . 你根本不会解决这个问题 . 如果您监视服务器,您将看到它现在可能正在耗尽大部分RAM甚至交换到磁盘 .
您可能应该尝试在代码中跟踪有问题的代码并进行修复 .
在Drupal 7中,您可以修改站点/默认文件夹中settings.php文件中的内存限制 . 在第260行附近,你会看到:
即使你的php.ini设置足够高,如果没有在你的Drupal settings.php文件中设置,你将无法消耗超过128MB .
即使在
php.ini
中设置了memory_limit
,并且phpinfo()
正确读出了值,我仍然收到此错误 .通过改变它:
对此:
这解决了PHP 7中的问题 .
我在以前工作的数据集上运行时遇到了以下错误 .
由于对故障的搜索将我带到了这里,我认为我并不总是上面的技术解决方案,而是更简单的东西 . 就我而言,它是Firefox . 在我运行该程序之前,它已经使用了1,157M .
事实证明,我是专家在没有考虑的情况下纠正的那种解决办法,但对于我这样的人来说,值得一试 .
如果您正在运行WHM驱动的VPS(虚拟专用服务器),您可能会发现您没有权限直接编辑PHP.INI;系统必须这样做 . 在WHM主机控制面板中,转到服务配置> PHP配置编辑器,修改memory_limit:
像这样运行脚本(例如cron case):
php5 /pathToScript/info.php
产生相同的错误 .正确的方法:
php5 -cli /pathToScript/info.php
您可以通过更改fastcgi / fpm上的memory_limit来正确解决此问题
更改内存,如128到512,见下文
至
不确定这个答案是否有任何帮助,但当我从我的代码中删除以下行时,一切正常!
include_once( '净/ SSH2.php'); include_once( '净/ SFTP.php');
这些行包含在每个正在运行的文件中,当逐个运行文件时都工作正常,但是当一起运行所有文件时,我遇到了内存泄漏问题 . 不知何故,“include_once”不包括一次,或者我做错了什么 .
在PHP脚本中很容易出现内存泄漏 - 尤其是在使用抽象时,例如ORM . 尝试使用Xdebug来分析您的脚本并找出所有内存的去向 .
正确的方法是编辑
php.ini
文件 . 根据您的愿望值编辑memory_limit
.从您的问题来看,已超出
128M
(这是默认限制),因此您的代码存在严重问题,因为它不应该占用太多 .如果你知道它为什么需要这么多而且你想让它设置为
memory_limit = 512M
或更高,你应该是好的 .如果您的代码的一部分可以使用大量内存,而不是更改
php.ini
文件中的memory_limit
值,则可以在该部分运行之前删除memory_limit
,然后在之后替换它 .当使用array_push向数组中添加2250万条记录时,我使用4G作为php.ini中的内存限制,在大约20M记录中不断出现“内存耗尽”致命错误 . 为了解决这个问题,我添加了声明
在文件的顶部 . 现在一切正常 . 我不知道php是否有内存泄漏,这不是我的工作,也不关心 . 我只需要完成我的工作,这很有效 .
该程序非常简单:
致命错误指向第3行,直到我提高了内存限制,从而消除了错误 .
PHP 5.3允许您通过在
public_html
文件夹中放置.user.ini
文件来更改内存限制 . 只需创建上述文件并在其中键入以下行:某些cPanel主机仅接受此方法 .
CRASH page?
(当MySQL必须查询大行时会发生这种情况,默认情况下,momory_limit设置为较小,这对硬件来说更安全)
在增加
php.ini
之前,您可以检查系统的现有内存状态在这里,我将其增加为以下,然后
service httpd restart
来修复CRASH页面问题 .我发现在包含或要求时它很有用:
dbconnection.php,_functions.php在实际处理的文件中,
而不是包括在 Headers 上 . 这包括在内 .
因此,如果包含 header 和 footer ,只需在包含 Headers 之前包含所有功能文件 .
对于那些为了找到原因而在地球上找到原因的人来说,这个小函数应该会导致内存泄漏,有时会出现一点点错误,函数会以递归方式自动启动 .
例如,对于要代理它的对象的函数具有相同名称的代理类 .
有时你可能会忘记带上那个小的actualObjec成员,因为Proxy实际上有doSomething方法,PHP不会给你任何错误,对于一个大类,它可以隐藏在眼睛里几分钟,找出原因它正在泄漏记忆 .
Your site's root directory:-
对于Drupal用户,这个Chris Lane的答案是:
有效,但我们需要在开幕后才提出来
标记在站点根目录的index.php文件中 .
启用这两行后 .
它开始工作了