|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-08-30 16:12 UTC] mail at milianw dot de
Description:
------------
When you setup an array and unset() it afterwards, not all memory is freed. I've run the code below on various PHP versions, including 5.2.6 (via Xampp) on Linux and Windows and always get output like:
startup: 64296
array setup: 13789672
unsetted array: 129284
The end value is more than twice as large as the start value.
Also interestingly is that low values in the for loop [e.g. for($i = 0; $i < 1; ++$i)] result in outputs like
startup: 64296
array setup: 64864
unsetted array: 64864
Could it be that unset() relies on the Garbage Collector to do the work instead of really destroying the variables? But then I find it strange that even if I put a sleep(10) after the unset I still get the same outputs for "unsetted array".
Reproduce code:
---------------
<?php
echo "startup: ".memory_get_usage()."\n";
$array = array();
for ($i = 0; $i < 100000; ++$i) {
$array[] = 'foobar';
}
echo "array setup: ".memory_get_usage()."\n";
unset($array);
echo "unsetted array: ".memory_get_usage()."\n";
Expected result:
----------------
My expectations would be that the value reported at the end would be nearly equal to the startup value.
Additionally a call to unset() should (imo) not rely on the GC but do the deleting itself instantaneously.
NOTE: I've seen http://bugs.php.net/bug.php?id=41713 which tells a similar story, but it should be fixed as far as the bug report tells. Additionally it was Windows only yet I spotted the described behaviour first on a Linux machine.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 24 18:00:02 2025 UTC |
So there is simply no way at all to delete / free / unset variables in PHP? But why does it work perfectly (i.e. like I imagine it should) when I unset a string, even a very large one? That one frees the memory instantaneously. But not so for arrays. I simply cannot see the reasoning behind this. When a programmer calls unset he seems to know that this very variable can be freed, or not? So why do we need to wait for a GC to step in and do the actual cleanup? As far as my limited knowledge goes manual delete/free is compatible with a GC, or not? Or is it only possible to free simple strings, ints etc. but not arrays? Take this code: ~~~~ <?php function foo() { $string = ''; for ($i = 0; $i < 1000; ++$i) { $string .= 'asdfasdfasdf'; } } $i = 0; echo "setup:\t".memory_get_usage()."\n"; for (; $i < 10; ++$i) { foo(); echo "run $i:\t".memory_get_usage()."\n"; } ~~~~ Output: setup: 65524 run 0: 66108 run 1: 66184 run 2: 66248 and constant thereafter. If I know change the code slightly: ~~~~ <?php function foo() { $array = ''; for ($i = 0; $i < 1000; ++$i) { $array[] = 'asdfasdfasdf'; } } $i = 0; echo "setup:\t".memory_get_usage()."\n"; for (; $i < 10; ++$i) { foo(); echo "run $i:\t".memory_get_usage()."\n"; } ~~~~ The output becomes: setup: 65364 run 0: 130356 run 1: 130364 run 2: 130384 run 3: 130344 and thereafter either that value or 130364 Ok - it's not a leak per se, yet I wonder: A function I called which setup an array should free that memory (or should get its memory freed) after stepping out of it's scope, no? Just like it does with strings... Also: I can append the following code to the last snippet to verify that the memory is _never_ freed: ~~~~ while (true) { echo memory_get_usage()."\n"; } ~~~~ I actually altered it a bit to break when the memory consumption changes, and could potentially wait for hours. So is this really no bug? Could it not be that e.g. some internal hash pointers are left behind without getting deleted?