#45954 [Bgs]: memory leak with unset(array)

2008-09-02 Thread scottmac
 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)

2008-09-02 Thread mail at milianw dot de
 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)

2008-09-01 Thread mail at milianw dot de
 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