3

i have a memory problem in php. I have set the limit in php.ini to 512 M

the output of /var/log/apache2/error.log is:

PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 71 bytes) in /var/www/phpgraphlib.php on line 578,

the interesting piece of code is:

 foreach ($saved_test_figurestoprint as $figuretoprint){
        if (strpos($obj[$figuretoprint],",") >0 ){
  $graphfilename= "graphfile".remove_invalid_chars_for_file($obj["_id"])."_".remove_invalid_chars_for_file($figuretoprint).".png" ;        
        $graph = new PHPGraphLib(1000,200,$graphfilename);
        $data = explode(',', $obj[$figuretoprint]); 
$graph->addData($data);
$graph->setTitle($figuretoprint);
$graph->setBars(false);
$graph->setLine(true);
$graph->setDataPoints(true);
$graph->setDataPointColor('maroon');
$graph->createGraph();
?> <td> <?  echo $figuretoprint ; ?></td> <td> <? 
echo <<<END
<imag src=$graphfilename>
END

?> </td></tr><tr><?
echo "</br></br>";
echo "used memory is ".memory_get_usage(true) . "\n";   

the latest output is : used memory is 30408704

i am using a 64bit ubuntu and php 5.3. Linux mongo-db-server 2.6.35-28-generic #49-Ubuntu SMP Tue Mar 1 14:39:03 UTC 2011 x86_64 PHP Version 5.3.3-1ubuntu9.3 the problem arises if there are > 40 images to draw.

i think the new memory limit is not been applied to the server i have found this bug http://bugs.php.net/52061 but is only for memory limits > 2GB

can you help me ?

Yoshi
  • 54,081
  • 14
  • 89
  • 103
sotiris
  • 39
  • 1
  • 2
  • I could be interesting ti have the output of your last line (used memory is ...). – deadalnix Jun 01 '11 at 09:22
  • Also have a look at [memory_get_peak_usage](http://php.net/manual/en/function.memory-get-peak-usage.php) – Yoshi Jun 01 '11 at 09:24
  • 1
    destruct / unset your PHPGraphLib class... – Aaria Carter-Weir Jun 01 '11 at 09:33
  • i have added unset($graph); echo "used memory is ".memory_get_usage(true) . "\n"; echo "memory peak is ".memory_get_peak_usage(true) . "\n"; and the output is still at the same levels used memory is 30670848 memory peak is 34340864. This is far too low , compared with my 512MB limit – sotiris Jun 01 '11 at 10:11
  • eh? I thought the problem was to stop it using 512Mb, if its only using 34Mb then it worked? It's still a ridiculous amount of memory to use for a program which generates a web page - but the reasons for that are more deep in your application. – symcbean Jun 01 '11 at 12:25
  • I'm not sure if this has been sorted in PHP 5.3 but I know in 5.2 the memory management is a bit lacking - even if you destroy an object the memory it used doesn't get freed up. I bet if you output memory_get_usage after each iteration you'll see it going up and up... I had a similar problem with a PDF creator script that created a lot of PDFs. The solution I had was to put a wrapper class around the PDF generator which actually executed the PDF creation via exec(). Not v pretty I grant you but it worked as each PDF was created in its own process. – james-geldart Jun 01 '11 at 15:33
  • you are right. the memory keeps increasing in every graph i display despite the unset($graph) used memory is 3407872 used memory is 14942208 used memory is 19922944 used memory is 20971520 used memory is 21495808 used memory is 21495808 used memory is 22544384 used memory is 23592960 used memory is 22806528 used memory is 22544384 . I will try your solution – sotiris Jun 02 '11 at 08:38
  • 1
    hello again. i have solved the problem. it seems that there was a specific entry in the mongo database that was causing it. for some reason it was preserving huge amounts of memory. it may be corrupted. i have removed it and now everything runs smoothly. – sotiris Jun 02 '11 at 11:35

2 Answers2

0

First thing I would do is make sure you are restarting your web server fully after making the php.ini change.

If that doesn't work, then try this:

  1. Make sure you are writing to the correct php.ini file. Make a info.php file and ensure you're writing to the correct one.

  2. At the bottom of your for loop do:

unset($graph); unset($data);

Those seem to be the largest variables and are clearly accumulating data and not being picked up by the garbage collector.

Jason Palmer
  • 731
  • 4
  • 17
  • I don't think unset'ing the variables will help, reassigning the variables at the top of the loop makes it quite clear to the garbage collector that the old memory can be freed. – Dana the Sane Jun 05 '11 at 20:08
  • I've seen scenarios where the garbage collector simply isn't fast enough. This may be one of them. It can't HURT to unset the variables. – Jason Palmer Jun 05 '11 at 20:24
0

PHP unset just removes the reference to the object and it does not clears the internal object memory allocation, so on iterative process where you are creating large objects every time then do make a destroy function of your object and in that function unset each class variables used, then only unsettling the main object will free whole memory it is occupying.. hope this fact helps anybody

  • `unset($variableReferringToA)` decreases the reference counter of an object `A` as well as the reference counters of all objects `B`, `C`, `D`, … that `A` refers to by one. When the counter for an object reaches 0, the object can/will be removed from memory. So you could say that `unset` works recursively. It is not necessary to write a class destructor to `unset` all instance variables. – mermshaus Jul 14 '11 at 18:11