Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for managing memory in a PHP script?

Tags:

Memory management is not something that most PHP developers ever need to think about. I'm running into an issue where my command line script is running out of memory. It performs multiple iterations over a large array of objects, making multiple database requests per iteration. I'm sure that increasing the memory ceiling may be a short term fix, but I don't think it's an appropriate long-term solution. What should I be doing to make sure that my script is not using too much memory, and using memory efficiently?

like image 431
Andrew Avatar asked Sep 22 '11 15:09

Andrew


People also ask

How does PHP manage memory?

PHP memory management functions are invoked by the MySQL Native Driver through a lightweight wrapper. Among others, the wrapper makes debugging easier. The various MySQL Server and the various client APIs differentiate between buffered and unbuffered result sets.

What should PHP memory limit be set to?

A typical appropriate memory limit for PHP running Drupal is 128MB per process; for sites with a lot of contributed modules or with high-memory pages, 256MB or even 512MB may be more appropriate.

How do I monitor PHP memory usage?

The memory_get_usage function can be used to track the memory usage. The 'malloc' function is not used for every block required, instead a big chunk of system memory is allocated and the environment variable is changed and managed internally. The above mentioned memory usage can be tracked using memory_get_usage().

How much memory does each PHP process consume?

When I set the PHP memory limit to e.g. 128 MB for each of these daemons, the processes will only get killed once they reach 128 MB according to PHP's own measurements. However, according to ps , the processes will be using around 200 MB each by that time.


1 Answers

The golden rule

The number one thing to do when you encounter (or expect to encounter) memory pressure is: do not read massive amounts of data in memory at once if you intend to process them sequentially.

Examples:

  • Do not fetch a large result set in memory as an array; instead, fetch each row in turn and process it before fetching the next
  • Do not read large text files in memory (e.g. with file); instead, read one line at a time

This is not always the most convenient thing in PHP (arrays don't cut it, and there is a lot of code that only works on arrays), but in recent versions and especially after the introduction of generators it's easier than ever to stream your data instead of chunking it.

Following this practice religiously will "automatically" take care of other things for you as well:

  • There is no longer any need to clean up resources with a big memory footprint by closing them and losing all references to them on purpose, because there will be no such resources to begin with
  • There is no longer a need to unset large variables after you are done with them, because there will be no such variables as well

Other things to do

  • Be careful of creating closures inside loops; this should be easy to do, as creating such inside loops is a bad code smell. You can always lift the closure upwards and give it more parameters.
  • When expecting massive input, design your program and pick algorithms accordingly. For example, you can mergesort any amount of text files of any size using a constant amount of memory.
like image 179
Jon Avatar answered Oct 06 '22 09:10

Jon