Fixing PHP Fatal error: Allowed memory size of (X) bytes exhausted.

This is a guide on how to avoid and / or fix one of PHP’s most common fatal errors: The memory exhausted error. Here is an example of what this error might look like:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in your-script.php on line 4

PHP’s memory limit.

If you encounter this error, it means that your PHP script has used up more memory than it is allowed to. If you open the php.ini configuration file that your web server is using, you will come across the following directive:

The memory_limit directive defines the maximum amount of memory that a PHP script can consume. In the example above, that has been set to 128MB. This means that if one of my PHP scripts consumes more than 128MB in memory, that nasty memory exhausted error will be thrown and the script will die.

If you do not have access to your php.ini file, then you can check what your server’s memory limit is using PHP’s init_get function like so:

Here’s a sample PHP script that I wrote to create this error:

In the code above, I looped through 900,000 times using PHP’s range function and added the md5 hash of each value to an array. After running the script above, I immediately received a fatal error telling me that my script had consumed too much memory.

Common causes.

In my experience, this issue is mostly caused by large PHP arrays, especially in some of the earlier versions of PHP (it is worth pointing out that PHP 7 consumes far less memory and is far better optimized).

A few cases where you might run into this memory exhausted error:

  • Selecting rows from a database and then adding them to a PHP array is fine most cases. However, if you are indiscriminately returning millions of rows and columns, this might become a bit of an issue.
  • If your script has large arrays and a lot of loops, there is a good chance that you might run out of memory. This is especially true if you have multiple loops and / or you are calling a lot of functions inside of those loops.
  • Recursively looping through large multi-dimensional arrays can prove to be an issue.
  • Dynamically creating or resizing images on-the-fly.

To be honest, 99% of the time, the reason I encountered this memory error was because I had underestimated the size of the array that I was dealing with. That or one of my SQL joins was missing a condition and it returned far more rows than I was expecting.

Fixing this error.

On some of the various PHP help forums, I have come across people offering solutions such as:

In the above piece of code, PHP’s ini_set function is being used to dynamically increase the amount of memory that the script can use. This is a horrible solution because it doesn’t try to fix the underlying problem and it could potentially lead to your web server running out of RAM. This line of code attempts to paper over the cracks by giving the script 1GB of memory – far more than what should ever be needed.

A more dangerous example:

This essentially tells the PHP script that there is no limit to the amount of memory it can use.

To fix this issue, a better approach is to:

  • Use a debugger such as Xdebug to profile your script and find out where the memory leak is coming from.
  • Make sure that your PHP arrays are not getting too large and that you are avoiding any unnecessary loops. i.e. If you have two loops for the same array, then you should probably try to find a way to combine them into one.
  • Be careful about the amount of data that you are returning from your database. If you are returning a lot of rows from your database, then you should make sure that you are only selecting the columns that your script is going to use. i.e. Don’t be lazy by doing a “SELECT * FROM” as that will return every column, even though your script might only be using two of them.
  • Use PHP’s unset function to destroy variables that you are no longer using, as this can help free up more memory for your script. i.e. If you have just looped through a large array that you no longer intend on using, then you can destroy it by passing it into the unset function.

Hopefully, this article helped to clear a few issues up!

Facebook Comments