Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fatal error: Out of memory, but I do have plenty of memory (PHP)

Tags:

php

memory

I ran accross the same kind of problem with the server dying when trying to use the swap. This is because mod_php does not free memory ever. So Apache processes keep growing either reaching apache or PHP's memory limit or, if there's no limit, crashing the server.

Restarting apache makes it to spawn new fresh slim processes but as they run PHP scripts over time, they grow until problems arise.

The solution is to make apache to kill processes after a certain number of queries served so it will create new ones ( There are some questions related to that) reducing the MaxRequestsPerChild configuration option to, let's say 100 (Defaults to 1000).

Of course this may reduce server performances as it takes ressources to kill and spawn new processes but at least it keeps the site working. You might be tempted to raise the number of running processes to keep performances high, be sure PHP (or apache) memory limit x max number of processes do not get over your server's physical ram.

Here's my experience, hope it helps.


For starters, memory_get_peak_usage() will not be helpful here. It will only return the amount of memory which was allocated, and that is the same number which caused the error.

memory_get_usage will return the active amount of memory which is being allocated when it is called.

ini_set('memory_limit', '256M'); will set the maximum allowance of PHP's footprint on your systems Memory. If you are getting OOM at 768K, upping it will not fix the problem.

There is no indication as to what version of PHP you are using, but I would suggest an upgrade immediately. There are several bugs where Zend's Memory Manager fails to deallocate memory, which would lead you exactly to the same problem.

Are both your local server and your production server running the same version of OS, the same long bit and the same version of PHP? The answer will be no.

If it is unrelated to the windows malloc() issue, being it is a sub domain and probably within a VirtualHost, and allocating only 768k, it almost sounds like an OS issue.

Run tasklist from the command prompt when you access your script. Do you see an additional Apache thread, or Memory usage across the processes spike?

One last idea is, run flush() and/or ob_flush(); after each loop for the table row/column. This should clear your buffer and save you some memory in the event this is where the issue is occurring.


I would start by upgrading PHP to 5.4+ as it's up to 50% faster for some applications. They fixed a large number of memory leaks. Please see becnhamrks: http://news.php.net/php.internals/57760


Please note that the error is Out of memory and is not Allowed memory size [..] exhausted.

So the memory leak is elsewhere on the system. It's possible that mysql server use a lot of system memory after this heavy query, leaving apache/php without it physical and swap.

This should explain the error always on the same line (and/or in the same script).


Install xdebug and enable profiler trigger. Generate a profiler file, then post the cachegrind file if you still would not be able to tell the source of the problem.

EDIT: profiler file of the page where the memory leak happens of course!


I would guess that you either haven't edited the right php.ini or you haven't restarted PHP and/or the webserver.

Create a phpinfo.php page in your docroot with the contents <?php phpinfo(); to make sure you are changing the correct php.ini. In addition to the location of the php.ini file the webserver is using, it will also state the maximum script memory allowed.

Next, I would add some stack traces to your page so you can see the chain of events that led to this. The following function will catch fatal errors and provide more information about what happened.

register_shutdown_function(function()
{
    if($error = error_get_last())
    {
        // Should actually log this instead of printing out...
        var_dump($error);
        var_dump(debug_backtrace());
    }
});

Personally, Nginx + PHP-FPM is what I have used for years since I left slow ol' Apache.