Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find which PHP script is leaking memory?

My dedicated server has 32GB RAM and the memory just goes up and up constantly and I have to reboot it daily now. This is costing me customers and money.

I am having a hard time finding where the memory leak is. All I can find online is people say "Use xdebug" but I haven't been able to find any xdebug tutorials on finding memory leaks. I have tried printing memory_get_usage before and after function calls but is that the right way to do it?

I have MANY php scripts running - some from visitors, others from cron jobs - and I need to find which one(s) of them is leaking memory and fix it ASAP but I don't even know how to determine if a given function is leaking memory or not.

I have tried printing memory_get_usage before a function call and after, and it goes up, but then if I call the function more than once, it doesn't go up anymore. Can someone please explain this and tell me how I can simply and easily tell if a PHP function has a memory leak?

like image 873
Guy Avatar asked Apr 17 '13 19:04

Guy


People also ask

How can I tell which program is causing memory leaks?

One way to check for memory leak is to press and hold down your Windows key and tap the Pause/Break key to bring up System Properties. Click on the Performance tab and check System Resources for the percentage of free or available RAM.

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().


2 Answers

You could do various things, but first you should try to avoid the creation of memory leaks in the first place.

Let me clarify: PHP is a scripting language and it is not designed for long running scripts, so it's memory management is not the best on the market. But why should it be? It's purpose is to be called on a request level so its running scope is quite small (not more than 2 - 3 seconds). Everything else should be put in the background.

What can I do against memory leaks?

  1. If you are at a version below 5.4 you need to take care of circle references, since those are not garbage collected.

  2. If you need a script to be run continuously, you might think about a different approach. Do try a while(true) implementation, but wrap supervisor (http://supervisord.org) around your script, and let it be called after it ends. That way you make 100% sure you never get memory leaks.

  3. You could use xdebug to profile your scripts one by one and find out, where a lot of memory is consumed.

  4. You could implement a destructor to unset all you references if the class is not of any need anymore.

    public function __destruct(){     $this->cleanup(); }  public function cleanup() {     //cleanup everything from attributes     foreach (get_class_vars(__CLASS__) as $clsVar => $_) {         unset($this->$clsVar);     }      //cleanup all objects inside data array     if (is_array($this->_data)) {         foreach ($this->_data as $value) {             if (is_object($value) && method_exists($value, 'cleanUp')) {                 $value->cleanUp();             }         }     } } 
  5. Read through the PHP documentation regarding garbage collection http://us3.php.net/manual/en/features.gc.php

  6. Avoid global variables, because those are never garbage collected and need to be unset explicitly. If you are using a Framework like ZF or Symfony that might not be possible, since you would break functionality if you do.

Last but not least I want to emphasize once again, PHP is not suited for long running scripts! If you have things to do, that need to run continuously you should not crumble your head with memory leaks in PHP, but take the time to learn a more sophisticated language like JAVA or C#.

like image 164
MatthiasLaug Avatar answered Sep 28 '22 17:09

MatthiasLaug


Look at this php-extension: https://github.com/arnaud-lb/php-memory-profiler. You will can dump information in different formats and simple analyze it by some tools such as: Google Performance Tools, KCacheGrind or QCacheGrind.

like image 45
Volodymyr Chumak Avatar answered Sep 28 '22 18:09

Volodymyr Chumak