php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #25853 CLI application not freeing used memory even with unset
Submitted: 2003-10-13 13:17 UTC Modified: 2003-10-13 21:20 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: morgan at mindviz dot com Assigned:
Status: Not a bug Package: CGI/CLI related
PHP Version: 4.3.3 OS: RedHat Linux 8.0
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: morgan at mindviz dot com
New email:
PHP Version: OS:

 

 [2003-10-13 13:17 UTC] morgan at mindviz dot com
Description:
------------
Basically I'm writing a php-CLI server application that 
will never exit unlike an apache process. I have been 
attempting to find out why slowly but surely the memory 
usage of my CLI app steadily goes up until it has 
exhausted all my available memory.

The server app will read in large data sets at times 
and then attempts to free those with the unset 
function. With further inspection it seems that even 
though unset is called the script still has a hold on 
or uses the allocated memory and never returns it to 
the system.

The code below is a small script that I put together to 
show the issue I am seeing, it is quite easy to 
reproduce the problem.

As with my server application if the script below was 
run forever and the max value of $z in the loop was set 
extremely high it would run until all the system's 
memory was used up, since unset is not actually 
returning any of the used memory for the test_array 
back to the system.

Reproduce code:
---------------
#!/root/php-4.3.3/php -n
<?php
    $my_pid = getmypid();

    echo "GOT PID: ".`ps -eo %mem,rss,pid | grep $my_pid`."\n";

    for($z = 0; $z < 10; $z++) {
        $test_array = array();

        // Build a Test 5x(1000*$z) array, will show incremental mem usage and after unset
        // line will test_array's memory will not be free'd
        for($i = 0; $i < 5; $i++) {
            for($j = 0; $j < 1000*$z; $j++) {
                $test_array[$i][$j] = "testing $i $j\n";
            }
        }

        echo "$z: MEMORY USAGE BEFORE UNSET ( % KB PID ) : ".`ps -eo %mem,rss,pid | grep $my_pid`;
        unset($test_var);
        echo "$z: MEMORY USAGE  AFTER UNSET ( % KB PID ) : ".`ps -eo %mem,rss,pid | grep $my_pid`."\n";
    }

    exit;
?>

Expected result:
----------------
GOT PID:  0.1 1524  3178

0: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.1 1532  
3178
0: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

1: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.2 2132  
3178
1: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

2: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.3 2740  
3178
2: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

3: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.3 3368  
3178
3: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

4: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.4 3952  
3178
4: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

5: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.5 4620  
3178
5: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

6: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.5 5204  
3178
6: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

7: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.6 5792  
3178
7: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

8: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.7 6376  
3178
8: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

9: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.7 7124  
3178
9: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1524  
3178

Actual result:
--------------
GOT PID:  0.1 1524  3178

0: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.1 1532  
3178
0: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.1 1532  
3178

1: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.2 2132  
3178
1: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.2 2132  
3178

2: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.3 2740  
3178
2: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.3 2740  
3178

3: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.3 3368  
3178
3: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.3 3368  
3178

4: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.4 3952  
3178
4: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.4 3952  
3178

5: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.5 4620  
3178
5: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.5 4620  
3178

6: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.5 5204  
3178
6: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.5 5204  
3178

7: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.6 5792  
3178
7: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.6 5792  
3178

8: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.7 6376  
3178
8: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.7 6376  
3178

9: MEMORY USAGE BEFORE UNSET ( % KB PID ) :  0.7 7124  
3178
9: MEMORY USAGE  AFTER UNSET ( % KB PID ) :  0.7 7124  
3178

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-10-13 20:16 UTC] sniper@php.net
I was a bit fast with this, thanks to Ilia who pointed out the flaws in your example. Try the following and you'll
see that unset() does free the memory just fine:

#!/root/php-4.3.3/php -n
<?php
    $my_pid = getmypid();

    for($z = 0; $z < 10; $z++) {
        $test_array = array();

        for($i = 0; $i < 5; $i++) {
           $test_array[] = str_repeat("testing", 100000);
        }

        echo "$z: MEMORY USAGE BEFORE UNSET ( % KB PID ) : ".`ps -eo %mem,rss,pid | grep $my_pid`;
        unset($test_array);
        echo "$z: MEMORY USAGE  AFTER UNSET ( % KB PID ) : ".`ps -eo %mem,rss,pid | grep $my_pid`."\n";
    }

    exit;
?>


 [2003-10-13 20:33 UTC] morgan at mindviz dot com
Ya that worked, why does it not free it when I use 
assignments like this:

$test_array[$i][$j] = "testing $i $j";

It would be most informative since I need to find a way 
to fix my code now.
 [2003-10-13 20:51 UTC] morgan at mindviz dot com
It is not practical to use str_repeat in the example 
since it would probably never be used in that case or 
many cases as a matter of fact.

Why won't this work ( all that was done switching the 
str_repeat line with 'testing' ):

#!/root/php-4.3.3/php -n
<?php
    $my_pid = getmypid();

    for($z = 0; $z < 10; $z++) {
        $test_array = array();

        for($i = 0; $i < 5; $i++) {
           $test_array[] = 'testing';
;
        }

        echo "$z: MEMORY USAGE BEFORE UNSET ( % KB PID 
) : ".`ps -eo
%mem,rss,pid | grep $my_pid`;
        unset($test_array);
        echo "$z: MEMORY USAGE  AFTER UNSET ( % KB PID 
) : ".`ps -eo
%mem,rss,pid | grep $my_pid`."\n";
    }

    exit;
?>

- I have also tried setting a variable to 'testing' 
outside of all loops and assigning $test_array[] = 
$the_str_variable; like that and it doesn't free the 
memory either.
 [2003-10-13 20:53 UTC] morgan at mindviz dot com
sorry about the last post, the code had an extra ; in 
it, here is the correct one that will produce the prob 
again but without the str_repeat to get the string to 
be assigned.

#!/root/php-4.3.3/php -n
<?php
    $my_pid = getmypid();

    for($z = 0; $z < 10; $z++) {
        $test_array = array();

        for($i = 0; $i < 5; $i++) {
           $test_array[] = 'testing';
        }

        echo "$z: MEMORY USAGE BEFORE UNSET ( % KB PID 
) : ".`ps -eo
%mem,rss,pid | grep $my_pid`;
        unset($test_array);
        echo "$z: MEMORY USAGE  AFTER UNSET ( % KB PID 
) : ".`ps -eo
%mem,rss,pid | grep $my_pid`."\n";
    }

    exit;
?>
 [2003-10-13 21:20 UTC] sniper@php.net
static content uses memory too.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 16 19:01:31 2024 UTC