Object Memory Leakage...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sorry folks, this is a long one...I've re-read a bunch of the documentation, and I can't find a solution.

In debugging an out of memory condition, I found that PHP doesn't seem to garbage collect unreferenced objects. It seems to work fine for anything other than objects. (Arrays, strings, integers, etc.)

Here's a simple example: define a class, create 3 instances, destroy them in reverse order. I would expect that after each unset and/or NULL, the memory usage would go down, they don't. See the output below.

<?php

class Tester {
       protected $test1;
       protected $test2;
       protected $test3;
       protected $test4;

       public function __construct() {
               $test1 = rand();
               $test2 = rand();
               $test3 = rand();
               $test4 = rand();
       }
}

echo memory_get_usage() . "\n";
$t1 = new Tester();
echo memory_get_usage() . "\n";
$t2 = new Tester();
echo memory_get_usage() . "\n";
$t3 = new Tester();
echo memory_get_usage() . "\n";
unset($t3);
$t3 = NULL;
echo memory_get_usage() . "\n";
$t2 = NULL;
echo memory_get_usage() . "\n";
unset($t1);
echo memory_get_usage() . "\n";


This outputs:

43344
43928
44232
44568
44640
44640
44640

Note: the memory usage remains constant after the objects are allocated, even when they're unset/NULL'ed.

Some of the user contributed notes on the PHP documentation suggest that the memory is actually freed and available for use by other variables/objects even though memory_get_usage() says otherwise. Another little test seems to disprove that too... The idea here is to allocate close to 8 MB, then free it to show that it can allocate that data within the memory limit. Then allocate enough class instances and free them again such that the memory usage increases enough that the same data allocated and freed initially doesn't fit anymore. If PHP did indeed free the objects, the data would fit the second time too...

<?php

ini_set('memory_limit','8m');

class Tester {
       protected $test;

       public function __construct() {
               $this->test = rand();
       }
}

echo "Initial Memory Usage: " . memory_get_usage() . "\n";

$mb = 6 * 1024 * 1024;
echo "Allocating 7 MB of data...";
$dat = "";
for ($x=0;$x<$mb;$x++) {
       $dat .= "x";
}
echo "Memory Usage: " . memory_get_usage() . "\n";
unset($dat,$x,$mb);
echo "Unset Usage: " . memory_get_usage() . "\n";

$num = 32767;
$objects = array();

echo "Initial Memory Usage (2): " . memory_get_usage() . "\n";
echo "Allocating $num objects...";
for ($x=0;$x<$num;$x++) {
       $objects[$x] = new Tester();
}
echo "Done. Memory Usage: " . memory_get_usage() . "\n";
echo "Freeing $num objects...";
for ($x=0;$x<$num;$x++) {
       unset($objects[$x]); $objects[$x] = NULL;
}
echo "Done. Memory Usage: " . memory_get_usage() . "\n";

$mb = 6 * 1024 * 1024;
echo "Allocating 7 MB of data...";
$dat = "";
for ($x=0;$x<$mb;$x++) {
       $dat .= "x";
}

This gives:

Initial Memory Usage: 44248
Allocating 7 MB of data...Memory Usage: 6335888
Unset Usage: 44448
Initial Memory Usage (2): 44504
Allocating 32767 objects...Done. Memory Usage: 7752920
Freeing 32767 objects...Done. Memory Usage: 2807080
Allocating 7 MB of data...
Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 1 bytes) in /home/janderson/svn/memtest.php on line 44


Am I missing something? (Is there a force_garbage_collection() function somewhere that I'm missing?) Any suggestions/workarounds/anything would be most appreciated.

Cheers,

jon

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux