What happens when your web host blames PHP memory_limit setting for memory usage issues on a Linux web server. This happened recently and although PHP’s memory limit was set to 1GB (very high) that does not mean that scripts were using 1GB. Let’s take a quick look at understanding PHP’s memory_limit setting.
PHP memory_limit is a per-script setting
PHP.net’s documentations puts it this way:
This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server...
Unlike say a MySQL’s key_buffer_size or innodb_buffer_pool settings, PHP’s memory_limit setting is not a storage space where multiple PHP scripts pool from or grow within. Rather it’s a per-script limit. PHP memory_limit is the amount of memory a single PHP script is allowed to consume before it’s blocked. When blocked, the resulting error output looks something like this:
Fatal error: Allowed memory size of x bytes exhausted (tried to allocate x bytes) in /path/to/php/script
or like this:
PHP Fatal error: Out of memory (allocated x) (tried to allocate x bytes) in /path/to/php/script
So for example, if two or more scripts are requested simultaneously, each is completely independent from the other. They do not share the memory_limit setting. Remember PHP is NOT designed for multithreading. It’s impossible for PHP to share memory between single-threaded scripts. So if five PHP scripts are simultaneously using 100MB each, that would total 500MB of PHP memory usage, and a PHP memory limit of 128M or 1G does not change or affect that.
That said, for scripts which request other PHP scripts inline using require, include or include_once, this limit is then inherited and shared by all included scripts that are dependent on the parent script.
The include statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement. The require() function is identical to include(), except that it handles errors differently. If an error occurs, the include() function generates a warning, but the script will continue execution. The require() generates a fatal error, and the script will stop.
The require_once() statement is identical to require() except PHP will check if the file has already been included, and if so, not include (require) it again.
Now regarding the original issue mentioned in the outset. A lower setting of 128M is always better because if there are PHP scripts trying to use more than 128M, those scripts would now return memory limit exceeded errors. In the above issue that was not the case, so regardless of 128M or 1G memory_limit setting it only comes into play if there’s inefficient script(s).
Fortunately, the PHP memory_limit setting will block inefficient code, which then alerts you so that you can optimize your script(s). Until fixed, you may have to temporarily increase the memory_limit setting, because any scripts which try to exceed the limit will not run and your web app will be broken in part or in whole.
If you don’t have them memory on your server, you’ll sometimes face with the decision to increase PHP memory_limit to meet requirements of scripts or, to optimize your code. You should always optimize when possible. Also, you can increase PHP’s memory limit for specific websites (one method would be to place a php.ini in the web root) and you can even set the limit for specific scriptname.php. For example using ini_set(‘memory_limit’,’256MB’).