Why does a PHP script constantly take up more memory?
See this example:
echo memory_get_usage() . "\n"; // 36640
$a = str_repeat("Hello", 4242);
echo memory_get_usage() . "\n"; // 57开发者_如何学Python960
unset($a);
echo memory_get_usage() . "\n"; // 36744
Can anyone explain why after un-setting the variable the memory usage does not return to 36640
If you do it twice the memory will stay at 36744...
echo memory_get_usage() . "\n"; // 36640
$a = str_repeat("Hello", 4242);
echo memory_get_usage() . "\n"; // 57960
unset($a);
echo memory_get_usage() . "\n"; // 36744
$a = str_repeat("Hello", 4242);
unset($a);
echo memory_get_usage() . "\n"; // -> 36744
Garbage collection is an expensive operation, even if there's only a single variable to unset. PHP won't run the collector each time you unset a var, as that'd waste a huge amount of CPU time.
PHP will only run the collector when it has to, as in when something wants more memory than is available.
What is your PHP version? The garbage collector in versions less than 5.3 is not really good. Please read this link to understand why:
Garbage collector
Just posting this.
I just ran it as a test for fun on PHP 5.3, the results are pretty clear to what powtac
said:
630744
652280
630808
630808
652280
630808
630808
652280
630808
630808
652280
630808
630808
652280
630808
630808
652280
630808
So yea, after the initial unset
it appears to be consistent throughout. Code tested with:
while (1) {
echo memory_get_usage() . "\n"; // 36640
$a = str_repeat("Hello", 4242);
echo memory_get_usage() . "\n"; // 57960
unset($a);
echo memory_get_usage() . "\n"; // 36744
}
Caution: that is an infinite loop :)
I'll try to give one possible explanation, but I cannot claim that it is the right one.
PHP stores variables in a hash table (because of it's dynamic nature). This hash table consists of "buckets" (linked lists of elements). As the number of elements grows the number of buckets is increased, too (to be precise: The number of buckets is doubled as soon as the limit is reached).
Thus it could be the case, that the creation of your variable results in an increase of buckets. As these buckets aren't removed again, the memory usage stays.
But again: Only guessing.
精彩评论