Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted (CodeIgniter + XML-RPC)

久未见 提交于 2019-11-25 22:57:09

问题


I have a bunch of client point of sale (POS) systems that periodically send new sales data to one centralized database, which stores the data into one big database for report generation.

The client POS is based on PHPPOS, and I have implemented a module that uses the standard XML-RPC library to send sales data to the service. The server system is built on CodeIgniter, and uses the XML-RPC and XML-RPCS libraries for the webservice component. Whenever I send a lot of sales data (as little as 50 rows from the sales table, and individual rows from sales_items pertaining to each item within the sale) I get the following error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes) 

128M is the default value in php.ini, but I assume that is a huge number to break. In fact, I have even tried setting this value to 1024M, and all it does is take a longer time to error out.

As for steps I\'ve taken, I\'ve tried disabling all processing on the server-side, and have rigged it to return a canned response regardless of the input. However, I believe the problem lies in the actual sending of the data. I\'ve even tried disabling the maximum script execution time for PHP, and it still errors out.


回答1:


Changing the memory_limit by ini_set('memory_limit', '-1'); is not a proper solution. Please don't do that.

Your PHP code may have a memory leak somewhere and you are telling the server to just use all the memory that it wants. You wouldn't have fixed the problem at all. If you monitor your server, you will see that it is now probably using up most of the RAM and even swapping to disk.

You should probably try to track down the offending code in your code and fix it.




回答2:


ini_set('memory_limit', '-1'); overrides the default PHP memory limit.




回答3:


The correct way is to edit your php.ini file. Edit memory_limit to your desire value.

As from your question, 128M (which is the default limit) has been exceeded, so there is something seriously wrong with your code as it should not take that much.

If you know why it takes that much and you want to allow it set memory_limit = 512M or higher and you should be good.




回答4:


The memory allocation for PHP can be adjusted permanently, or temporarily.

Permanently

You can permanently change the PHP memory allocation two ways.

If you have access to your php.ini file, you can edit the value for memory_limit to your desire value.

If you do not have access to your php.ini file (and your webhost allows it), you can override the memory allocation through your .htaccess file. Add php_value memory_limit 128M (or whatever your desired allocation is).

Temporary

You can adjust the memory allocation on the fly from within a PHP file. You simply have the code ini_set('memory_limit', '128M'); (or whatever your desired allocation is). You can remove the memory limit (although machine or instance limits may still apply) by setting the value to "-1".




回答5:


It's very easy to get memory leaks in a PHP script - especially if you use abstraction, such as an ORM. Try using Xdebug to profile your script and find out where all that memory went.




回答6:


When adding 22.5 million records into an array with array_push I kept getting "memory exhausted" fatal errors at around 20M records using 4G as the memory limit in file php.ini. To fix this, I added the statement

$old = ini_set('memory_limit', '8192M'); 

at the top of the file. Now everything is working fine. I do not know if PHP has a memory leak. That is not my job, nor do I care. I just have to get my job done, and this worked.

The program is very simple:

$fh = fopen($myfile); while (!feof($fh)) {     array_push($file, stripslashes(fgets($fh))); } fclose($fh); 

The fatal error points to line 3 until I boosted the memory limit, which eliminated the error.




回答7:


I kept getting this error, even with memory_limit set in php.ini, and the value reading out correctly with phpinfo().

By changing it from this:

memory_limit=4G 

To this:

memory_limit=4096M 

This rectified the problem in PHP 7.




回答8:


When you see the above error - especially if the (tried to allocate __ bytes) is a low value, that could be an indicator of an infinite loop, like a function that calls itself with no way out:

function exhaustYourBytes() {     return exhaustYourBytes(); } 



回答9:


After enabling these two lines, it started working:

; 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 




回答10:


You can properly fix this by changing memory_limit on fastcgi/fpm:

$vim /etc/php5/fpm/php.ini 

Change memory, like from 128 to 512, see below

; Maximum amount of memory a script may consume (128 MB) ; http://php.net/memory-limit memory_limit = 128M 

to

; Maximum amount of memory a script may consume (128 MB) ; http://php.net/memory-limit memory_limit = 512M 



回答11:


Your site's root directory:

ini_set('memory_limit', '1024M'); 



回答12:


For Drupal users, this Chris Lane's answer of:

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

works but we need to put it just after the opening

<?php 

tag in the index.php file in your site's root directory.




回答13:


Rather than changing the memory_limit value in your php.ini file, if there's a part of your code that could use a lot of memory, you could remove the memory_limit before that section runs, and then replace it after.

$limit = ini_get('memory_limit'); ini_set('memory_limit', -1); // ... do heavy stuff ini_set('memory_limit', $limit); 



回答14:


In Drupal 7, you can modify the memory limit in the settings.php file located in your sites/default folder. Around line 260, you'll see this:

ini_set('memory_limit', '128M'); 

Even if your php.ini settings are high enough, you won't be able to consume more than 128 MB if this isn't set in your Drupal settings.php file.




回答15:


Change the memory limit in the php.ini file and restart Apache. After the restart, run the phpinfo(); function from any PHP file for a memory_limit change confirmation.

memory_limit = -1 

Memory limit -1 means there is no memory limit set. It's now at the maximum.




回答16:


PHP 5.3+ allows you to change the memory limit by placing a .user.ini file in the public_html folder. Simply create the above file and type the following line in it:

memory_limit = 64M 

Some cPanel hosts only accept this method.




回答17:


Crash page?

(It happens when MySQL has to query large rows. By default, memory_limit is set to small, which was safer for the hardware.)

You can check your system existing memory status, before increasing php.ini:

# free -m              total       used       free     shared    buffers     cached Mem:         64457      63791        666          0       1118      18273 -/+ buffers/cache:      44398      20058 Swap:         1021          0       1021 

Here I have increased it as in the following and then do service httpd restart to fix the crash page issue.

# grep memory_limit /etc/php.ini memory_limit = 512M 



回答18:


For those who are scratching their heads to find out why on earth this little function should cause a memory leak, sometimes by a little mistake, a function starts recursively call itself for ever.

For example, a proxy class that has the same name for a function of the object that is going to proxy it.

class Proxy {      private $actualObject;      public function doSomething() {          return $this->actualObjec->doSomething();     } } 

Sometimes you may forget to bring that little actualObjec member and because the proxy actually has that doSomething method, PHP wouldn't give you any error and for a large class, it could be hidden from the eyes for a couple of minutes to find out why it is leaking the memory.




回答19:


I had the error below while running on a dataset smaller than had worked previously.

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in C:\workspace\image_management.php on line 173

As the search for the fault brought me here, I thought I'd mention that it's not always the technical solutions in previous answers, but something more simple. In my case it was Firefox. Before I ran the program it was already using 1,157 MB.

It turns out that I'd been watching a 50 minute video a bit at a time over a period of days and that messed things up. It's the sort of fix that experts correct without even thinking about it, but for the likes of me it's worth bearing in mind.




回答20:


Running the script like this (cron case for example): php5 /pathToScript/info.php produces the same error.

The correct way: php5 -cli /pathToScript/info.php




回答21:


If you're running a WHM-powered VPS (virtual private server) you may find that you do not have permissions to edit PHP.INI directly; the system must do it. In the WHM host control panel, go to Service ConfigurationPHP Configuration Editor and modify memory_limit:




回答22:


I find it useful when including or requiring _dbconnection.php_ and _functions.php in files that are actually processed, rather than including in the header. Which is included in itself.

So if your header and footer is included, simply include all your functional files before the header is included.




回答23:


Just add a ini_set('memory_limit', '-1'); line at the top of your web page.

And you can set your memory as per your need in the place of -1, to 16M, etc..




回答24:


This error is sometimes caused by a bug in the PHP code that causes recursions involving exception handling and possibly other operations. Unfortunately, I haven't been able to create a tiny example.

In these cases, which have happened for me several times, set_time_limit fails, and the browser keeps trying to load the PHP output, either with an infinite loop or with the fatal error message which is the topic of this question.

By reducing the allowed allocation size by adding

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

near the beginning of your code you should be able to prevent the fatal error.

Then you may be left with a program that terminates, but is still difficult to debug.

At this point insert BreakLoop() calls inside your program to gain control and find out what loop or recursion in your program is causing the problem.

The definition of BreakLoop is as follows:

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 

The $LoopSite argument can be the name of a function in your code. It isn't really necessary, since the error message you will get will point you to the line containing the BreakLoop() call.




回答25:


In my case it was a brief issue with the way a function was written. A memory leak can be caused by assigning a new value to a function's input variable, e.g.:

/** * 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'; } 



回答26:


Using yield might be a solution as well. See Generator syntax.

Instead of changing the PHP.ini file for a bigger memory storage, sometimes implementing a yield inside a loop might fix the issue. What yield does is instead of dumping all the data at once, it reads it one by one, saving a lot of memory usage.




回答27:


When I removed the following lines from my code, all worked OK!

set_include_path(get_include_path() . get_include_path() . '/phpseclib'); include_once('Net/SSH2.php'); include_once('Net/SFTP.php'); 

These lines were included in every file I was running. When running the files one by one, all worked OK, but when running all files together I got the memory leak issue. Somehow the "include_once" is not including things once, or I am doing something wrong...



来源:https://stackoverflow.com/questions/561066/fatal-error-allowed-memory-size-of-134217728-bytes-exhausted-codeigniter-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!