Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PHP's garbage collector slow down performance, and how to manage memory without it?

This relates to a PHP 5.3 Cli application that processes a lot of data in a complex way, taking hours to run. Someone discovered that turning off garbage collection made it run a great deal faster (maybe as much as 50%).

The only article I've come across that mentions this performance hit is http://derickrethans.nl/collecting-garbage-performance-considerations.html. I'm not sure I follow it entirely, but it seems to suggest that it only applies to code with a lot of circular references.

Could someone shed some light on this please?

Also, given that we have turned gc off, is there any way to manually reduce memory? Using unset() has been suggested. A quick test has shown that eighty or so bytes is freed by unset() regardless of the size of the object. This suggests it's just unsetting the reference, which is borne out by what I have read online. Am I right in thinking that these eighty bytes would be freed anyway, even without garbage collection, when the variable falls out of scope?

like image 673
naomi Avatar asked Jan 24 '13 12:01

naomi


1 Answers

You just disabled the circular-reference-GC. The regular one still works.

The common GC tests, whether or not there are zvals ("memory"), that are not referenced by any variables, or properties anymore, and will free this memory. A circular reference is, when two or more objects references each other directly, or indirectly

$a = new stdClass;
$b = new stdClass;
$a->b = $b;
$b->a = $a;
unset($a, $b);

Now both objects reference each other, but they are both not referenced from anywhere else, so they are unreachable. This is, what the circular-reference GC tries to detect, but to find them, it iterates over every known object and finds out, if there is a reference "from outside". Its a little bit more complicated, but simplified thats it ;) So in structures with many references, espcially circular ones, it is a huge task.

Worth to mention: With unset() you only remove the reference, but don't free the memory (directly). This is done by the GC later (and it makes a good job :))

like image 65
KingCrunch Avatar answered Sep 22 '22 09:09

KingCrunch