10

I have a script, that gets data send (about 16MB in size), which I read using php://input.

$in = file_get_contents("php://input");

But I'm running into memory limit issues, so I traced it down using memory_get_usage() and realized, that the script is already consuming 47MB memory on startup (before issuing any command).

My guess is, this is due to PHP pre-filing global variables. So I'm searching for a way to unset those, since I'm only reading the php://input stream.

I tried:

unset($GLOBALS);
unset($_SERVER);
unset($_GET);
unset($_POST);
unset($_FILES);
unset($_REQUEST);
unset($_ENV);
unset($_COOKIE);
unset($HTTP_RAW_POST_DATA);
unset($http_response_header);
unset($argc);
unset($argv);
gc_collect_cycles();

And it reduces the memory usage from 47MB to 31MB.

Is there anything else I can do, to have PHP consume less memory on startup?

It would give me more memory to work with the data I received.

JochenJung
  • 7,183
  • 12
  • 64
  • 113
  • My PHP Version is 5.4.9 – JochenJung Oct 19 '13 at 08:42
  • you could increase the memory_limit in your php ini file. Interesting question though! – kasper Taeymans Oct 19 '13 at 08:46
  • My provider won't increase it. And anyhow, I would prefer using less memory, than just increasing limits. – JochenJung Oct 19 '13 at 08:47
  • can you provide any details of what was the gain after each change?. I mean something like "after doing an unset($variable); I got 2 kb, after unset($other_variable); I got 2MB". Do you have a relation of the loaded modules? The 47 MB is after you have set some variables or is the same even with an empty page with just a memory_get_usage()? – PatomaS Mar 15 '14 at 05:50
  • Further to PatomaS' comment, are you sure your memory footprint is not 40 **k** rather than 40 **M**? On my box I am reading <100kB. Just to rule this out: `memory_get_usage()` returns a value in *bytes*. – RandomSeed Mar 15 '14 at 13:38
  • Please outline the exact way how you track the memory usage (at best, provide a small example that allows to reproduce your issue). Take care of all parameters to [`memory_get_usage`](http://php.net/memory_get_usage), especially `real_usage`, see [Tracking Memory Usage in PHP](http://stackoverflow.com/q/2290611/367456) - Another related question: [How to optimize the php process memory usage?](http://stackoverflow.com/questions/10353568/how-to-optimize-the-php-process-memory-usage) – hakre Mar 16 '14 at 14:14
  • @PatomaS: What you see above is the whole script. So I do not set any variables myselfe. But, the script receives Data (~16MB in size) – JochenJung Mar 17 '14 at 10:36
  • @RandomSeed: Yes, it is MB. Have you send 16MB POST data, when calling your script? – JochenJung Mar 17 '14 at 10:37
  • @JochenJung: OK that is all the script, but can you mention the gain for each variable aplied? You said you tried unsetting those variables, which means that you can comment all those, and dump the result of gc_collect_cycles() after reenabling each one, that will give us an insight of your system. Can you also tell us which operative system is the script being executed on and your access/control on that system? – PatomaS Mar 17 '14 at 10:56
  • on PHP Version 5.3.3-7+squeeze15 with standard config memory_get_usage(with "false" and "true") 618672 786432 phpinfo() 635320 786432 on PHP Version 5.4.4-14+deb7u8 with standard config 232288 262144 phpinfo() 278128 524288 277240 524288 on my provider: 5.4.4-14+deb7u8 237080 262144 phpinfo() 290456 524288 it should be something wrong with config from your provider. – vdd Mar 20 '14 at 09:55

4 Answers4

5

It is interesting that at startup your script is taking so much memory. But I'd suggest you to modify your program in such a way that it can work with lesser amount of memory.

$in = file_get_contents("php://input");

will load all the input data in memory, which is bad. Instead try to read a few KB's of data in memory, process it and the proceed with the rest until you have consumed all the data.

You can use http://php.net/manual/en/function.stream-get-line.php

adesh
  • 160
  • 4
  • The data I get, is JSON encoded. Afaik there is no serial json decode function. See http://stackoverflow.com/questions/15077870/serial-json-decode-due-to-memory-limit So unless, I would build one my own, I need to fetch all data. – JochenJung Oct 19 '13 at 09:16
  • 2
    If that is the case, then may be you can try this library to parse JSON https://github.com/kuma-giyomu/JSONParser. See http://stackoverflow.com/questions/4049428/processing-large-json-files-in-php – adesh Oct 19 '13 at 09:36
  • That could help. But I think its a good idea to minimize the memory usage at startup as well. For it is taking 47, of 100 MB memory limit, which is already half the memory the script has got. – JochenJung Oct 19 '13 at 12:02
3

Do you have xDebug enabled on your server? It could another extension like that. phpinfo() will tell you what extensions are installed.

What is the memory usage for a simple script like

<?php 
echo memory_get_usage(false) . "\n";
echo memory_get_usage(true) . "\n";
echo "test\n";
?>

Also try

var_dump(get_defined_vars()); 

to see all the variable loaded in your script.

vdd
  • 487
  • 5
  • 6
Chris Gunawardena
  • 6,246
  • 1
  • 29
  • 45
0

Send the data using Content-Type: application/json

PHP will not set $_POST variable then.

Marek
  • 7,337
  • 1
  • 22
  • 33
0

If it is allowed by your configuration and hardware you can increase the memory limit at runtime:

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

or increase it through .htaccess or apache configuration, as follows:

php_value memory_limit 128M
clami219
  • 2,958
  • 1
  • 31
  • 45