我有一堆客户销售点(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的最大脚本执行时间,但它仍然出错.
改变memory_limit
由ini_set('memory_limit', '-1');
是不是一个妥善的解决办法.请不要这样做.
您的PHP代码可能在某处出现内存泄漏,并且您告诉服务器只使用它想要的所有内存.你根本不会解决这个问题.如果您监视服务器,您将看到它现在可能正在耗尽大部分RAM甚至交换到磁盘.
您可能应该尝试在代码中跟踪有问题的代码并进行修复.
ini_set('memory_limit', '-1');
覆盖默认的PHP内存限制.
正确的方法是编辑您的php.ini
文件.memory_limit
根据您的愿望值编辑.
从您的问题来看,128M
(已经超出了默认限制),因此您的代码存在严重问题,因为它不应该占用太多.
如果你知道它为什么需要这么多而且你想允许它设置memory_limit = 512M
或更高,你应该是好的.
PHP的内存分配可以永久调整,也可以暂时调整.
您可以通过两种方式永久更改PHP内存分配.
如果您有权访问您的php.ini
文件,则可以根据需要编辑memory_limit
值.
如果您无权访问您的php.ini
文件(并且您的webhost允许),您可以通过.htaccess
文件覆盖内存分配.添加php_value memory_limit 128M
(或任何您想要的分配).
您可以在PHP文件中动态调整内存分配.你只需要代码ini_set('memory_limit', '128M');
(或任何你想要的分配).您可以通过将值设置为"-1"来删除内存限制(尽管可能仍适用机器或实例限制).
在PHP脚本中很容易出现内存泄漏 - 尤其是在使用抽象时,例如ORM.尝试使用Xdebug来分析您的脚本并找出所有内存的去向.
当使用array_push向数组中添加2250万条记录时,我使用4G作为php.ini中的内存限制,在大约20M记录中不断出现"内存耗尽"致命错误.为了解决这个问题,我添加了声明
$old = ini_set('memory_limit', '8192M');
在文件的顶部.现在一切正常.我不知道php是否有内存泄漏,这不是我的工作,也不关心.我只需要完成我的工作,这很有效.
该程序非常简单:
$fh = fopen($myfile); while (!feof($fh)) { array_push($file, stripslashes(fgets($fh))); } fclose($fh);
致命错误指向第3行,直到我提高了内存限制,从而消除了错误.
我一直收到这个错误,即使memory_limit
设置为php.ini
,并且正确读出的值phpinfo()
.
通过改变它:
memory_limit=4G
对此:
memory_limit=4096M
这解决了PHP 7中的问题.
当你看到上面的错误 - 特别是如果它(tried to allocate __ bytes)
是一个低值时,这可能是一个无限循环的指示器,就像一个无法自行调用自身的函数:
function exhaustYourBytes() { return exhaustYourBytes(); }
启用这两行后.
它开始工作了
; Determines the size of the realpath cache to be used by PHP. This value should ; be increased on systems where PHP opens many files to reflect the quantity of ; the file operations performed. ; http://php.net/realpath-cache-size realpath_cache_size = 16k ; Duration of time, in seconds for which to cache realpath information for a given ; file or directory. For systems with rarely changing files, consider increasing this ; value. ; http://php.net/realpath-cache-ttl realpath_cache_ttl = 120
您可以通过更改fastcgi/fpm上的memory_limit来正确解决此问题
$vim /etc/php5/fpm/php.ini
更改内存,如128到512,见下文
; Maximum amount of memory a script may consume (128 MB) ; http://php.net/memory-limit memory_limit = 128M
至
; Maximum amount of memory a script may consume (128 MB) ; http://php.net/memory-limit memory_limit = 512M
您网站的根目录: -
ini_set('memory_limit', '1024M');
对于Drupal用户,这个Chris Lane的答案是:
ini_set('memory_limit', '-1');
有效,但我们需要在开幕后才提出来
标记在站点根目录的index.php文件中.
13> 小智..:在Drupal 7中,您可以修改站点/默认文件夹中的settings.php文件中的内存限制.在第260行附近,你会看到:
ini_set('memory_limit', '128M');即使你的php.ini设置足够高,你将无法如果这是不是在你的Drupal的settings.php文件中设置消耗比128MB以上.
14> 小智..:如果您的代码的一部分可以使用大量内存,而不是更改文件中的
memory_limit
值php.ini
,则可以memory_limit
在该部分运行之前删除它,然后在之后替换它.$limit = ini_get('memory_limit'); ini_set('memory_limit', -1); // ... do heavy stuff ini_set('memory_limit', $limit);
15> Hasib Kamal..:从php.ini文件更改内存限制并重新启动apache.重新启动后运行phpinfo(); 函数来自任何php文件,用于memory_limit更改确认.
memory_limit = -1内存限制-1表示没有内存限制设置它现在是最大值.
16> 小智..:PHP 5.3+允许您通过在
.user.ini
文件public_html
夹中放置文件来更改内存限制.只需创建上述文件并在其中键入以下行:memory_limit = 64M某些cPanel主机仅接受此方法.
17> 小智..:CRASH页面?
(当MySQL必须查询大行时会发生这种情况,默认情况下,momory_limit设置为较小,这对硬件来说更安全)
在增加之前,您可以检查系统的现有内存状态
memory_limit
# free -m total used free shared buffers cached Mem: 64457 63791 666 0 1118 18273 -/+ buffers/cache: 44398 20058 Swap: 1021 0 1021在这里我增加了它,然后
php.ini
修复CRASH页面问题.# grep memory_limit /etc/php.ini memory_limit = 512M
18> madz..:对于那些为了找到原因而在地球上找到原因的人来说,这个小函数应该会导致内存泄漏,有时会出现一点点错误,函数会以递归的方式开始递归调用自身.
例如,对于要代理它的对象的函数具有相同名称的代理类.
class Proxy { private $actualObject; public function doSomething() { return $this->actualObjec->doSomething(); } }有时你可能会忘记带上那个小的actualObjec成员,因为Proxy实际上有doSomething方法,PHP不会给你任何错误,对于一个大类,它可以隐藏在眼睛里几分钟,找出原因它正在泄漏记忆.