How to protect PHP from running out of memory

Poor programming could result in the script running out of memory rather quickly, there are a great deal of factors that could cause this – not just improper programming techniques but lack of knowledge in what affects memory. Because of this I’ve decided to write a few notes and tips on improving performance and memory usage.

Memory for PHP is cleared up my PHPs garbage collector. Sadly the garbage collector is a little lazy. In fact, it never seems to get to work on time and as a result memory is not freed quick enough for the scripts to progress. To work inline with the garbage collector here are a few tips on improving your code:


Tip 1 (Knowing what parts of your script is using the most memory)
If you’re looking to find out where your script is running out of memory the following function would be your best bet:

memory_get_peak_usage();

This function will return the current memory usage at the point it is executed. You’ll eventually see where your script is using the most amount of memory, or in my case, where the garbage collector decided it would rather go on lunch than do its job.


Tip 2 (Reassign null to vars along with un-setting them)

The unset(); function is useful when the garbage collector is doing its rounds however until then the unset(); function simply destroys the variable reference to the data, the data still exists in memory and PHP sees the memory as inuse despite no longer having a pointer to it. The solution: Assign null to your variables to clear the data, at least until the garbage collector gets ahold of it.

$var = null;

You can also use unset(); to unset the variable pointer, however there is little difference in memory usage, as far as I can see:

unset($var);


Tip 3 (__destruct your object references upon disposing of an object)

PHP does not release memory dedicated to an objects internal references to other objects until the garbage collector gets round to it. Because of this it’s worth adding a __destruct method to your objects which unsets all references to other objects. This can drastically help lower memory usage and is often ignored.

protected function __distruct()
{
  $this->childObject = null;
}


Tip 4 (Use functions where possible)

Upon the ending of an in use function PHP clears the memory it was using, at least more efficiently than if not using a function. If you are using recursive code or something similar that is memory intensive try putting the code into a function or method, upon closing of the function/method the memory used for the function will be garbaged much more efficiently than that of unsetting variables within the loop itself.


Tip 5 (Cache your filesystem checks, such as file_exists)

Checking if a file or directory exists before creating it, knowing a directory may be checked more than once? Using file_exists(); costs memory, not much, granted, but it does. The solution? Store the file paths you’ve already checked in an array (Or object property) and use in_array();

if(!in_array($path, $this->path_list))
{
  // ... Your code to deal with the file
}


Tip 6 (Database access is expensive)

Accessing a database is expensive, if you don’t have to, don’t. Based on tip 5, I am checking the filesystem despite being able to access the database to see if an asset exists. A lot more processing is required to access a database than there is checking the filesystem.


Tip 7 (Do not use objects if not needed)

Unless little or no performance difference I find it best to not using objects when obtaining data from a database, unless updating them. Objects add extra overhead for your scripts, as a result I tend to follow this rule of thumb:

– If not writing to a database, do not use objects, use arrays
– If you will be modifying data in a database, use objects – it tends to be cleaner and somewhat more efficient in the long run.

Related Posts