致命错误: 允许内存大小为134217728字节耗尽(CodeIgniter + XML-RPC)

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.

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

csdnceshi66
必承其重 | 欲带皇冠 Possible duplicate of Allowed memory size of 33554432 bytes exhausted (tried to allocate 43148176 bytes) in php
4 年多之前 回复
csdnceshi78
程序go Summary downvoted all the "just ignore the leak" answers, people who confused CodeIgniter with Drupal and people who just copy and pasted other peoples' answers to get points. The quality of answers in this one is abysmal.
接近 7 年之前 回复
csdnceshi72
谁还没个明天 memory limit is 128MB, souble it: ini_set('memory_limit', '256M');
大约 7 年之前 回复
csdnceshi69
YaoRaoLov Here is the code I am using... I have included the XML-RPC library used for the client as well: yousendit.com/download/U0d4SlIzcVg4aVBIRGc9PQ (Client) yousendit.com/download/U0d4SlIzcVhPSHhMWEE9PQ (Codeigniter Controller) Thanks for your time, in advance. :)
11 年多之前 回复
csdnceshi69
YaoRaoLov The error seems to occur either during the client sending, or the server receiving. I've tried disabling all serverside processing, and rigging it to send a canned response regardless of the data sent. The error occurs if I send over a certain amount of data. I am changing the PHP.ini setting.
11 年多之前 回复
csdnceshi73
喵-见缝插针 How/where are you setting the memory_limit to 1024M?
11 年多之前 回复
csdnceshi57
perhaps? I'm a bit confused... where does the error occur - in the client or server? And at which stage... client sending, server receiving, server processing, server sending, client receiving or client processing?
11 年多之前 回复

23个回答

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.

csdnceshi61
derek5. That removes the memory_limit, which you only want if you're monitoring memory usage some other way. The OS will kill the process if it's taking a huge amount of memory at some point any way.
大约 5 年之前 回复
weixin_41568196
撒拉嘿哟木头 memory_limit = -1 ; set in php.ini
大约 6 年之前 回复
csdnceshi76
斗士狗 Yeha, however try to avoid huge memory use, if the number of users are going to be more
6 年多之前 回复
csdnceshi50
三生石@ Honestly, if your caching some serious amounts of data, this is the correct answer. 128M is not enough for certain scripts. 512M or 1024M will often be enough, but you have to decide case by case.
6 年多之前 回复

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.

weixin_41568110
七度&光 what to track on the fresh installation, error log just says that "Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)"
3 年多之前 回复
csdnceshi69
YaoRaoLov There better solution not to store all data in memory and use database cursors and php yield, fetch data row by row and place it in your report. Here is small example with cursors and yield generators github.com/stepchik/stuff/tree/master/php_memory_problem
接近 4 年之前 回复
csdnceshi69
YaoRaoLov In most common way this trouble in ORM when you try to fetchAll data that much more php memory limit. For example when you try to generate monthly report.
接近 4 年之前 回复
csdnceshi64
游.程 But how do you track down this kind of error?
4 年多之前 回复
csdnceshi62
csdnceshi62 in the cases you named for the remaining 5% read the data in chunks and use a worker to process it instead of using more memory. This solution will scale as well while your suggestion won't work except your keep stuffing more and more memory into your server over the time if the data grows.
5 年多之前 回复
weixin_41568134
MAO-EYE I fully agree, a value of -1 could be useful only in dev environments to test purposes.
5 年多之前 回复
csdnceshi76
斗士狗 yes you are right that sometimes a process requires more memory but you should increase the memory limit to some logical amount like 256MB as you said or 512MB why not BUT not -1 ;)
大约 6 年之前 回复
csdnceshi71
Memor.の you are probably right 95% of the time. However, there are times when you actually do need more memory. For example, let's say your app is loading a massive amount of data into memory for processing (say a Bill of Material with 15k components). It is not always the case that the code is buggy, sometimes you just need a little bit more memory (e.g. 256M instead of 128M). However I agree that setting it to -1 is horribly bad. But adjusting the memory limit for reasonable situations at run-time is perfectly acceptable imho.
6 年多之前 回复

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

csdnceshi70
笑故挽风 Works really well with high loaded production program, thanks infinitely !
接近 3 年之前 回复
weixin_41568134
MAO-EYE Thanks man.. can't stand all the comments bashing this reply, all the assumptions made are simply hilarious... Who says a person needs this for an app that will be constantly running and consuming memory?? I'm trying to do a very large data dump from the DB and getting this error. I'm not going to re-run this script ever again, so what's wrong with this solution?? Downvote ferries on SO need to take it easy..
接近 3 年之前 回复
csdnceshi65
larry*wei Best answer... Thank you
3 年多之前 回复
csdnceshi66
必承其重 | 欲带皇冠 Always think before you use this, if it is really neccessary.
3 年多之前 回复
csdnceshi63
elliott.david This is a very bad idea
接近 5 年之前 回复
csdnceshi64
游.程 Sad to see that the answer for +161 votes and -3 votes is the same :(
大约 5 年之前 回复
csdnceshi58
Didn"t forge With all due respect, this answer should be down-voted into oblivion. This solution "fixes" one problem, but introduces a host of other problems. It's like trading away the one devil you've got in return for dozens of more devils. As has already been suggested, (1) increase global PHP memory availability in memory_limit in php.ini and/or (2) diagnose the memory leak.
5 年多之前 回复
csdnceshi67
bug^君 this is not the correct way even this is much upvoted. this will lead to poor performance code.
5 年多之前 回复
csdnceshi69
YaoRaoLov memory_get_usage(true) may come handy if you are trying to figure out precisely where the memory outage is happening. This way you can try to improve your script performance without excessive memory consumption.
接近 6 年之前 回复
csdnceshi73
喵-见缝插针 you made my day sir... congrats! +1 (+10 if I could...)
6 年多之前 回复
csdnceshi52
妄徒之命 then set it to a sane value. You could prevent the script from throwing the error by setting it to 1024M. If this answer said ini_set('memory_limit', '1024M'); You could copy-paste that and be ok. By setting it to -1 you are setting yourself up to have a script that consumes all memory. Especially if you do this routinely. Putting "dangerous" in quotes doesn't make it any less dangerous. You really could hose your host server. Maybe start destroying data. I don't know, maybe lose your job? Sounds pretty dangerous to me. :|
6 年多之前 回复
csdnceshi54
hurriedly% It's the best answer. I'm setting this a lot because I have PHP scripts I run on my desktop where I couldn't care less about the "dangerous" consequences. I just want to prevent the script from throwing that error, that's all.
6 年多之前 回复
csdnceshi52
妄徒之命 Shame that this gets so many upvotes. Setting it to an accurate value, with either php.ini edits or ini_set, is a perfectly valid solution when people need more memory. Setting it to unlimited is a dangerous hack :(
6 年多之前 回复
csdnceshi75
衫裤跑路 - it will also consume resources the server can't spare.
6 年多之前 回复
csdnceshi51
旧行李 combined with max_execution_time = -1 this can consume all resources the server can spare.
接近 7 年之前 回复
weixin_41568127
?yb? -1 is a value PHP understands as unlimited in this context.
接近 7 年之前 回复
csdnceshi61
derek5. In certain situations where you absolutely need something to complete and then change this back to a reasonable setting, this really helps.
大约 7 年之前 回复
weixin_41568208
北城已荒凉 Why does -1 in the ini_set work though?
大约 7 年之前 回复
csdnceshi55
~Onlooker where should one change that?! I only find that line in php.ini
7 年多之前 回复

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.

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

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 128MB if this isn't set in your Drupal settings.php file.

csdnceshi64
游.程 There is also no string in settings.php for drupal 6
2 年多之前 回复
csdnceshi55
~Onlooker Not in Drupal7 there is no such string of code in settings.php
7 年多之前 回复

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 Configuration > PHP Configuration Editor, modify memory_limit:

Updating memory_limit on WHM 11.48.4

For those who are scratching their hairs to find out why in 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 would'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.

weixin_41568208
北城已荒凉 And another tip: you can put die('here') in your code and move that statement around to see where the recursion starts.
2 年多之前 回复

I find it useful when including or requiring:
dbconnection.php, _functions.php in files that are actually processed,
rather than including on header. Which is included itself.

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

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 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.

csdnceshi71
Memor.の What a luxury it would be to have time to go and optimize a script for something like that. Or research and compare and learn ETL tools or some such. In the real world, we jack the memory allowance way up, do the thing, and move on.
2 年多之前 回复
csdnceshi58
Didn"t forge best solution ! it worked for me!
大约 4 年之前 回复
csdnceshi52
妄徒之命 you mean ini_set('memory_limit', '8192M'); ?
接近 5 年之前 回复
共23条数据 1 3 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐