14

I have a weird memory problem in PHP. I think something is only allowing an array to be a maximum of 0.25M. It appears the script is only using up to around 6M before it crashes.

Here's the output from xdebug:

enter image description here

Here's the function it is calling. The result of the sql query is about 800 rows of text.

public function getOptions(){
    $sql = "select Opt,
                   Code,
                   Description
            from PCAOptions";

    $result = sqlsrv_query($this->conn,$sql);

    $arrayResult = array();
    echo ini_get('memory_limit'); //this confirms that my memory limit is high enough
    while($orderObject = sqlsrv_fetch_object($result,'PCA_Option')){
        array_push($arrayResult, $orderObject);
    }
    return $arrayResult;
}
ck_
  • 3,353
  • 5
  • 31
  • 33
Westwick
  • 2,367
  • 3
  • 28
  • 51
  • 6
    nitpick, use `$arrayResult[] = $orderObject;` as it uses less resources. This is indeed strange though. – Prisoner Jan 18 '13 at 17:11
  • There is an overhead induced by the PHP structures to make arrays and objects - not sure how much it costs in this case. But check the actual size of the output from the *mysql* command line tool... sometimes we have some surprises :-) – Déjà vu Jan 18 '13 at 17:11
  • 2
    What was your memory limit set to? – David Schwartz Jan 18 '13 at 17:14
  • 2
    You can see in the screenshot the output of the ini_get('memory_limit') -- 1024M – Westwick Jan 18 '13 at 17:14
  • 2
    Try `memory_get_usage(true)` to check how much memory script use. – Viacheslav Kondratiuk Jan 18 '13 at 17:17
  • @viakondratiuk I tried echoing that after each array_push and it seemed to match up with what xdebug was giving me in the memory column. – Westwick Jan 18 '13 at 17:18
  • And of course arrays have overhead, you can read http://nikic.github.com/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html – Viacheslav Kondratiuk Jan 18 '13 at 17:19
  • 3
    Almost looks like there's a `ini_set("memory_limit", "256K")` where there should be a `ini_set("memory_limit", "256M")` – Alex Howansky Jan 18 '13 at 17:21
  • You may have already tried this, but does increasing the `memory_limit`, further, allow the script to complete successfully? – Prisoner Jan 18 '13 at 17:25
  • @prisoner just tried it with 2048M and got the exact same results. – Westwick Jan 18 '13 at 17:29
  • same numbers reported by xdebug? – Prisoner Jan 18 '13 at 17:30
  • Everything was the same up until step #5 but at that point it was only a difference of about 500 bytes. – Westwick Jan 18 '13 at 17:32
  • This code is part of some framework? Can you create separate script and try do the same query in it? – Viacheslav Kondratiuk Jan 18 '13 at 17:35
  • Perhaps when you fetch from `sqlsrv_query` it acquires results from the database, and old results are marked for garbage collection but not actually deleted? – Waleed Khan Jan 18 '13 at 17:36
  • I checked my xdebug and everything reported correct numbers for me, which makes me think it's more of a config issue. Is there any way you can set the memory within your php.ini file or through .htaccess? Is this happening locally? If so, change your php.ini `memory_limit` and restart httpd. – Prisoner Jan 18 '13 at 17:40
  • I have the memory_limit set in both my php.ini and my .htaccess. This method is part of a class that extends Mage_Shell_Abstract which does check the .htaccess file and call ini_set on php variables in the constructor, but I've stepped through it and confirmed it is setting it to 1024M. – Westwick Jan 18 '13 at 17:46
  • Can you post that file please, well, the memory relevant stuff. – Prisoner Jan 18 '13 at 17:47
  • http://pastebin.com/zDc8H4V0 – Westwick Jan 18 '13 at 17:52
  • Does your httpd not handle parsing of the .htaccess file using `php_value memory_limit 1024M`? Secondly, does the script throw any errors if your don't suppress the `ini_sets` on lines 116 and 122 (remove the `@`'s)? – Prisoner Jan 18 '13 at 17:53
  • also, might be worth checking this question & answer: http://stackoverflow.com/a/5860101/475125 - apart from that, good luck getting it fixed and if you work it out please be sure to post the solution, I'm puzzled as to whats going on! – Prisoner Jan 18 '13 at 18:03
  • This discussion is growing too long and hard to follow. However it contains good information which should be integrated into the post. Please do that! – markus Jan 19 '13 at 14:17

3 Answers3

1

So, I don't know how or why this worked, but I fixed the problem by commenting out these two lines from my .htaccess file:

#    php_value memory_limit 1024M
#    php_value max_execution_time 18000

I did this because I noticed phpinfo() was returning different values for these settings in the two columns "master" and "local".

My php.ini had memory_limit=512M and max_execution_time=3000, whereas my .htacces file had the above values. I thought .htaccess would just override whatever was in php.ini but I guess it caused a conflict. Could this be a possible bug in php?

Westwick
  • 2,367
  • 3
  • 28
  • 51
  • Sounds like a bug, but is it in apache, mod-php or php it's self? I would [submit it as a bug to php](https://bugs.php.net/) and see what they say. – Mark Tomlin Jan 20 '13 at 10:20
0

There's a number of steps some PHP distributions, security packages, and web hosts take to prevent users from raising the PHP actual memory limit at runtime via ini_set. The most likely candidate is the suhosin security package.

This older Stack Overflow question has a number of other suggestions as well.

Community
  • 1
  • 1
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
-2

When working with 'big' scripts which i know will bypass my server PHP memory limits, i always set this variable at the beginning of the script. Works all the time.

ini_set("memory_limit","32M"); //Script should use up to 32MB of memory
Herbert Musoke
  • 317
  • 2
  • 5
  • it works all the time, but unless you actually want your scripts to run continues, for days if not weeks or months, you are better of setting a very large value, for example: `set_time_limit(86400); // 24 hours` You wouldn't be the first to lock up a server. – Jacco Jan 20 '13 at 11:23
  • Answer and comment are off topic. In question is a "memory limit", not a "time limit" problem. – Jens A. Koch Jan 20 '13 at 12:29