ID:               36482
 Updated by:       [EMAIL PROTECTED]
 Reported By:      K dot Londenberg at librics dot de
-Status:           Open
+Status:           Bogus
 Bug Type:         Scripting Engine problem
 Operating System: Linux 2.6.12-1-386
 PHP Version:      5.1.2
 New Comment:

See bug #33595.


Previous Comments:
------------------------------------------------------------------------

[2006-02-21 21:26:16] K dot Londenberg at librics dot de

Verified with latest CVS Source Snapshot (5.1-200602211930)
of the 5.1x series:
http://snaps.php.net/php5.1-200602211930.tar.gz
Built On: Feb 21, 2006 19:30 GMT

Built with these options:
./configure --prefix=/opt/test --without-apache --disable-pdo
--without-sqlite  --without-pear

php --version returns the following:

PHP 5.1.3-dev (cgi) (built: Feb 21 2006 21:14:14)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies

------------------------------------------------------------------------

[2006-02-21 20:32:59] K dot Londenberg at librics dot de

By accident, I posted the *working* version as example code. To provoke
the bug, you need to uncomment the line containing
"$bigd->subdata->subdata = $bigd;"

------------------------------------------------------------------------

[2006-02-21 20:30:18] K dot Londenberg at librics dot de

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 this bug report at http://bugs.php.net/?id=36482&edit=1

Reply via email to