1

There's a memory leak in my script and I couldn't find it after 2 days. I found the loop that is causing the memory leak; each iteration of the loop increases the memory usage. I moved the loop into a function to isolate the variables. At the end of the function, I unsetted every variable created by the function so that get_defined_vars() returns an empty array. Here's what I mean:

function the_loop(){
  $var="value";

  ... // processing, including using a library

  unset($var);
  print_r(get_defined_vars()); // prints empty array
}

while(true){
  the_loop();
  echo memory_get_usage()."\n"; // steadily increases until memory limit is reached
}

I'm guessing that some variables defined in the_loop() are still in memory. I tried using XDebug's trace tool, but it didn't help. All it showed was that memory usage increases on average over the long run. I'm looking for a tool that can show me all the values in PHP's memory. I will be able to recognize the variable based on the value. What tool can dump PHP's memory?

Leo Jiang
  • 24,497
  • 49
  • 154
  • 284
  • 2
    unset does not instantly free the memory a variable was using, the php garbage collector does that –  Jul 17 '14 at 00:57
  • What version of PHP do you use? PHP before 5.3 had no cycle collection mechanism. Also read: http://php.net/manual/en/features.gc.collecting-cycles.php – sectus Jul 17 '14 at 01:14
  • I'm using version 5.5 – Leo Jiang Jul 17 '14 at 03:16
  • 1
    @Dagon PHP frees the memory at the end of a function, hence `the_loop()` – Leo Jiang Jul 17 '14 at 03:16
  • 1
    @Linksku "PHP frees the memory at the end of a function" can you site a source for that claim? –  Jul 17 '14 at 03:56
  • http://stackoverflow.com/questions/14082870/does-php-free-local-variables-immediately-after-the-function-ends Here – Leo Jiang Jul 18 '14 at 17:57
  • Anyway, I found the problem. There was a caching mechanism that got too big. I disabled the cache and it works now. – Leo Jiang Jul 18 '14 at 17:58

2 Answers2

3

As Dragon mentioned unset doesn't instantly free memory.

What's better at freeing memory with PHP: unset() or $var = null

I'd consider re-evaluating the way you're using PHP, it's not designed for long/constant running scripts, the garbage handler simply isn't that great.

If you want to dig further into the executing script I'd suggest checking out some tools like:

https://github.com/jokkedk/webgrind

http://xhprof.io/

http://derickrethans.nl/xdebug-and-tracing-memory-usage.html

Also worth a read: What gc_collect_cycles function is useful for?

Community
  • 1
  • 1
Tom
  • 591
  • 4
  • 20
0

Calling unset() does not force garbage collection, so while the reference count should decrease there may be others referencing it. Use xdebug_debug_zval($var) before calling unset to see how many references to its value there actually are.

Ronen Botzer
  • 6,951
  • 22
  • 41