Php 致命错误:允许的内存大小134217728字节已用尽(CodeIgniter+;XML-RPC)
我有一堆客户销售点(POS)系统,它们定期将新的销售数据发送到一个集中的数据库,该数据库将数据存储到一个大数据库中以生成报告 客户端POS基于PHPPOS,我实现了一个模块,该模块使用标准XML-RPC库将销售数据发送到服务。服务器系统构建在CodeIgniter上,并为webservice组件使用XML-RPC和XML-RPCS库。每当我发送大量销售数据时(从sales表中只发送50行,从sales\u items中发送与销售中的每个项目相关的单独行),我都会收到以下错误:Php 致命错误:允许的内存大小134217728字节已用尽(CodeIgniter+;XML-RPC),php,codeigniter,memory,xml-rpc,memory-limit,Php,Codeigniter,Memory,Xml Rpc,Memory Limit,我有一堆客户销售点(POS)系统,它们定期将新的销售数据发送到一个集中的数据库,该数据库将数据存储到一个大数据库中以生成报告 客户端POS基于PHPPOS,我实现了一个模块,该模块使用标准XML-RPC库将销售数据发送到服务。服务器系统构建在CodeIgniter上,并为webservice组件使用XML-RPC和XML-RPCS库。每当我发送大量销售数据时(从sales表中只发送50行,从sales\u items中发送与销售中的每个项目相关的单独行),我都会收到以下错误: Fatal err
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)
128M是php.ini
中的默认值,但我认为这是一个需要打破的巨大数字。事实上,我甚至尝试将该值设置为1024M,它所做的只是需要更长的时间才能出错
至于我所采取的步骤,我已经尝试禁用服务器端的所有处理,并对其进行了操纵,使其返回一个固定响应,而不管输入是什么。然而,我相信问题在于数据的实际发送。我甚至尝试过禁用PHP的最大脚本执行时间,但仍然会出错。PHP脚本中很容易出现内存泄漏,特别是在使用抽象(如ORM)的情况下。尝试使用Xdebug分析脚本并找出所有内存的去向。
ini\u set('memory\u limit','-1')代码>覆盖默认值。对于Drupal用户,Chris Lane的回答是:
ini_set('memory_limit', '-1');
工作,但我们需要把它放在开幕后
<?php
在Drupal 7中,您可以在sites/default文件夹中的settings.php文件中修改内存限制。在第260行附近,您将看到:
ini_set('memory_limit', '128M');
即使您的php.ini设置足够高,如果Drupal settings.php文件中没有设置,您也无法消耗超过128MB的内存。正确的方法是编辑php.ini
文件。
编辑memory\u limit
到您想要的值
从您的问题来看,128M
(这是默认限制)已被超过,因此您的代码存在严重错误,因为它不应该占用那么多时间
如果你知道为什么需要这么多,并且你想允许它设置内存限制=512M
或更高,你应该很好。通过ini\u set('memory\u limit','-1')更改内存限制
代码>不是合适的解决方案。请不要那样做
您的PHP代码可能在某个地方有内存泄漏,您正在告诉服务器只使用它想要的所有内存。你根本无法解决这个问题。如果您监视您的服务器,您将看到它现在可能正在使用大部分RAM,甚至正在交换到磁盘
您可能应该尝试跟踪代码中的错误代码并修复它。PHP5.3+允许您通过将.user.ini
文件放在公用html
文件夹中来更改内存限制。
只需创建上述文件并在其中键入以下行:
memory_limit = 64M
某些cPanel主机只接受此方法。启用这两行后,它开始工作:
; 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
PHP的内存分配可以永久调整,也可以临时调整
永久地
您可以通过两种方式永久更改PHP内存分配
如果您有权访问php.ini
文件,则可以将内存限制
的值编辑为所需的值
如果您无权访问php.ini
文件(并且您的Web主机允许),您可以通过.htaccess
文件覆盖内存分配。添加php\u值内存\u限制128M
(或任何您想要的分配)
暂时的
您可以在PHP文件中动态调整内存分配。您只需设置代码ini_集('memory_limit','128M')代码>(或任何您想要的分配)。通过将该值设置为“-1”,您可以删除内存限制(尽管计算机或实例限制可能仍然适用)。您站点的根目录:
ini_set('memory_limit', '1024M');
通过更改fastcgi/fpm上的内存\u限制
,可以正确修复此问题:
$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
到
当您看到上述错误时,尤其是当(试图分配u u;字节)
是一个低值时,这可能是一个无限循环的指示器,就像一个调用自身却没有出路的函数:
function exhaustYourBytes()
{
return exhaustYourBytes();
}
如果您运行的是WHM支持的VPS(虚拟专用服务器),您可能会发现您没有直接编辑PHP.INI的权限;系统必须做到这一点。在WHM主机控制面板中,转至维修配置→ PHP配置编辑器和修改内存限制
:
当使用array_push将2250万条记录添加到一个数组中时,我在文件php.ini中使用4G
作为内存限制,在大约2000万条记录中不断出现“内存耗尽”致命错误。为了解决这个问题,我添加了声明
$old = ini_set('memory_limit', '8192M');
在文件的顶部。现在一切正常。我不知道PHP是否有内存泄漏。那不是我的工作,我也不在乎。我只需要完成我的工作,这就行了
程序非常简单:
$fh = fopen($myfile);
while (!feof($fh)) {
array_push($file, stripslashes(fgets($fh)));
}
fclose($fh);
致命错误指向第3行,直到我提高了内存限制
消除了错误。对于那些正在绞尽脑汁想知道为什么这个小函数会导致内存泄漏的人来说,有时由于一个小错误,一个函数开始递归地永远调用自己
例如,对于要代理它的对象的函数,具有相同名称的代理类
class Proxy {
private $actualObject;
public function doSomething() {
return $this->actualObjec->doSomething();
}
}
有时您可能会忘记带上ActualLobJEC小成员,因为代理实际上有doSomething
方法,PHP不会给您任何错误,对于一个大型类,它可能会被隐藏几分钟,以找出它泄漏消息的原因
class Proxy {
private $actualObject;
public function doSomething() {
return $this->actualObjec->doSomething();
}
}
# free -m
total used free shared buffers cached
Mem: 64457 63791 666 0 1118 18273
-/+ buffers/cache: 44398 20058
Swap: 1021 0 1021
# grep memory_limit /etc/php.ini
memory_limit = 512M
memory_limit=4G
memory_limit=4096M
$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);
memory_limit = -1
/**
* Memory leak function that illustrates unintentional bad code
* @param $variable - input function that will be assigned a new value
* @return null
**/
function doSomehting($variable){
$variable = 'set value';
// Or
$variable .= 'set value';
}
function BreakLoop($MaxRepetitions=500,$LoopSite="unspecified")
{
static $Sites=[];
if (!@$Sites[$LoopSite] || !$MaxRepetitions)
$Sites[$LoopSite]=['n'=>0, 'if'=>0];
if (!$MaxRepetitions)
return;
if (++$Sites[$LoopSite]['n'] >= $MaxRepetitions)
{
$S=debug_backtrace(); // array_reverse
$info=$S[0];
$File=$info['file'];
$Line=$info['line'];
exit("*** Loop for site $LoopSite was interrupted after $MaxRepetitions repetitions. In file $File at line $Line.");
}
} // BreakLoop
$stmt->bindParam(":PERIOD", $period);
empty string ''
$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = $id";
$stmt = getConnection()->query($sql);
$courseDetails = $stmt->fetchAll(PDO::FETCH_ASSOC)
$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = ?";
$stmt = getConnection()->prepare($sql);
$stmt->execute(array($id));
sudo cp /etc/php.ini.default /etc/php.ini
sudo nano /etc/php.ini
php -i | grep php.ini
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini
php -r "echo ini_get('memory_limit').PHP_EOL;"
$table = "<table>\n";
$table .= "<tbody>\n";
foreach ($data as $item) {
$table .= "<tr>\n";
// this caused the Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted
$table .= "<td>$item->description</td><td>$item->qty</td>" .
$table .= "<td>$item->price_incl</td><td>$item->price->vat</td>" .
$table .= "<td>$item->price_excl</td><td>$item->available</td>" .
$table .= "</tr>\n";
}
$table .= "</tbody>";
$table .= "</table>\n";