From:             K dot Londenberg at librics dot de
Operating system: Linux 2.6.12-1-386
PHP version:      5.1.2
PHP Bug Type:     Scripting Engine problem
Bug description:  Garbage Collector - bug with circular references.

Description:
------------
The PHP Garbage Collector fails to free objects which are unreachable if
they contain circular references to each other.

The example script does not provoke an out of memory error, but I have
some cases where a script hits the memory limit, even if there are loads
of unreachable objects to be finalized. 

Sorry, but the example code has 32 lines. I guess it won't break your big
repository anyway.

Compare what happens if you run the example script as it is, and what
happens if you uncomment the line containing
"$bigd->subdata->subdata = $bigd;"

If you want to test this script in a PHP Engine without large memory
limits, just lower the numbers.

BTW - this is a real problem and does happen quite frequently. All you
need is some kind of circular reference between some objects, and
everything referenced by those objects won't be cleared by the Garbage
Collector until script termination.

Reproduce code:
---------------
<?php
    // This Test case demonstrates a bug where the PHP Garbage Collector
fails
    // to release objects which are unreachable but contain circular
references.
    
  class bigdata {
    private $data;
    public $subdata;
    public function __construct($entries) {
            $this->data = array();
            echo "Creating BIGDATA with $entries entries\n";
            if ($entries>=1000) {
                    $this->subdata = new bigdata($entries/2);    
            }
            for ($i=0;$i<$entries;$i++) { $this->data[] = $i; }
    }
        public function __destruct() {
                echo "Destroyed BIGDATA with ".count($this->data)."
entries\n";
        }
    }
  echo "<PRE>";
  echo "Creating bigdata\n";flush();
  $bigd = new bigdata(1000);
  echo "Removing reference to bigdata\n";flush();
  $bigd = null;
  echo "Creating new bigdata\n";flush();
  $bigd = new bigdata(1000);
  echo "Creating circular reference. \n";flush();
  //$bigd->subdata->subdata = $bigd; // If you omit this statement, the
Gargabe collector will destroy everything as it should. 
  echo "Removing all global references to bigdata\n";flush();
  $bigd = null;
  echo "Now, exiting\n";flush();
  exit; 
?>

Expected result:
----------------
<PRE>Creating bigdata
Creating BIGDATA with 1000 entries
Creating BIGDATA with 500 entries
Removing reference to bigdata
Destroyed BIGDATA with 1000 entries
Destroyed BIGDATA with 500 entries
Creating new bigdata
Creating BIGDATA with 1000 entries
Creating BIGDATA with 500 entries
Creating circular reference. 
Removing all global references to bigdata
Destroyed BIGDATA with 1000 entries
Destroyed BIGDATA with 500 entries
Now, exiting

Actual result:
--------------
<PRE>Creating bigdata
Creating BIGDATA with 1000 entries
Creating BIGDATA with 500 entries
Removing reference to bigdata
Destroyed BIGDATA with 1000 entries
Destroyed BIGDATA with 500 entries
Creating new bigdata
Creating BIGDATA with 1000 entries
Creating BIGDATA with 500 entries
Creating circular reference. 
Removing all global references to bigdata
Now, exiting
Destroyed BIGDATA with 1000 entries
Destroyed BIGDATA with 500 entries

-- 
Edit bug report at http://bugs.php.net/?id=36482&edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=36482&r=trysnapshot44
Try a CVS snapshot (PHP 5.1): 
http://bugs.php.net/fix.php?id=36482&r=trysnapshot51
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=36482&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=36482&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=36482&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=36482&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=36482&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=36482&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=36482&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=36482&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=36482&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=36482&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=36482&r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=36482&r=php3
Daylight Savings:             http://bugs.php.net/fix.php?id=36482&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=36482&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=36482&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=36482&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=36482&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=36482&r=mysqlcfg

Reply via email to