#45954 [Bgs]: memory leak with unset(array)
ID: 45954 Updated by: [EMAIL PROTECTED] Reported By: mail at milianw dot de Status: Bogus Bug Type: Performance problem Operating System: * PHP Version: 5.2.6 New Comment: The internal memory manager is keeping tabs of the memory and will reuse it again if there is a memory allocation that it can fit in the block. You can use valgrind and see that the memory is in fact free'd when the request ends. Previous Comments: [2008-09-01 17:48:18] mail at milianw dot de 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? [2008-08-31 00:28:28] [EMAIL PROTECTED] unset() is not free(). PHP uses memory manager that does the actual garbage cleanup during request shutdown. [2008-08-30 16:12:43] 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 10; ++$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. -- Edit this bug report at http://bugs.php.net/?id=45954edit=1
#45954 [Bgs]: memory leak with unset(array)
ID: 45954 User updated by: mail at milianw dot de Reported By: mail at milianw dot de Status: Bogus Bug Type: Performance problem Operating System: * PHP Version: 5.2.6 New Comment: Yes, thank you. Thats an explanation which clarifies things for me. Though one last thing: I was not speaking about a memory leak which persists after the process is finished, but one while the process is running. I was interested because while optimizing GeSHi I searched for ways to reduce the memory consumption / memory peaks and spotted this behaviour. You can close this bug. Thanks again. Previous Comments: [2008-09-02 08:44:04] [EMAIL PROTECTED] The internal memory manager is keeping tabs of the memory and will reuse it again if there is a memory allocation that it can fit in the block. You can use valgrind and see that the memory is in fact free'd when the request ends. [2008-09-01 17:48:18] mail at milianw dot de 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? [2008-08-31 00:28:28] [EMAIL PROTECTED] unset() is not free(). PHP uses memory manager that does the actual garbage cleanup during request shutdown. [2008-08-30 16:12:43] 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 10; ++$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
#45954 [Bgs]: memory leak with unset(array)
ID: 45954 User updated by: mail at milianw dot de Reported By: mail at milianw dot de Status: Bogus Bug Type: Performance problem Operating System: * PHP Version: 5.2.6 New Comment: 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? Previous Comments: [2008-08-31 00:28:28] [EMAIL PROTECTED] unset() is not free(). PHP uses memory manager that does the actual garbage cleanup during request shutdown. [2008-08-30 16:12:43] 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 10; ++$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. -- Edit this bug report at http://bugs.php.net/?id=45954edit=1