Bug #48781 [Asn]: Cyclical garbage collector memory leak

[email protected]
Newsgroups php.bugs
Message-ID <[email protected]>
Edit report at http://bugs.php.net/bug.php?id=48781&edit=1

 ID:               48781
 Updated by:       [email protected]
 Reported by:      nate at frickenate dot com
 Summary:          Cyclical garbage collector memory leak
 Status:           Assigned
 Type:             Bug
 Package:          Scripting Engine problem
 Operating System: Debian 5.0 kernel 2.6.24-23-xen
 PHP Version:      5.3.0
 Assigned To:      dmitry

 New Comment:

Yeah. I confirm the problem. It looks like on each 100,000 iterations
PHP runs GC about 12 times. And on each GC run it looses 2 objects
referenced by $user. I'll try to fix it.


Previous Comments:
------------------------------------------------------------------------
[2010-04-18 02:28:35] [email protected]

I am unable to duplicate this behaviour using 5.3.2. The code given
below consistently uses 0.65 MB even up to 10 million iterations - I
pasted the output of up to 6 million, with the extended GC reporting
turned on:

<?php

class User {
    protected $profile;

    public function __construct () {
        $this->profile = new UserProfile($this);
    }
    
    public function dispose() {
		$this->profile->dispose();
		$this->profile = null;
    }
}

class UserProfile {
    private $user;

    public function __construct ($user) {
        $this->user = $user;
    }
    
    public function dispose() {
		$this->user = null;
    }
}

for ($userid = 1; ; $userid++) {
	if(isset($user)) {
		$user->dispose();
	}
    $user = new User;

    if ($userid % 100000 == 0)
        printf("memory usage after %s users: %s MB.\n",
number_format($userid), number_format(memory_get_usage() / 1024 / 1024,
2));

    continue;
}

?>


memory usage after 100,000 users: 0.65 MB.
memory usage after 200,000 users: 0.65 MB.
memory usage after 300,000 users: 0.65 MB.

[snip]

memory usage after 5,700,000 users: 0.65 MB.
memory usage after 5,800,000 users: 0.65 MB.
memory usage after 5,900,000 users: 0.65 MB.

GC Statistics
-------------
Runs:               0
Collected:          0
Root buffer length: 0
Root buffer peak:   9

      Possible            Remove from  Marked
        Root    Buffered     buffer     grey
      --------  --------  -----------  ------
ZVAL        16         7          7         0
ZOBJ  77999984  11999998   11999998         0

------------------------------------------------------------------------
[2010-01-05 19:31:01] nightstorm at tlen dot pl

I confirm, there is a true memory leak. Consider the following script,
where the references are unmounted manually with an extra dispose()
method:

~~~~
<?php

/*
How to use:
    a) run test 1 by running code as-is
    b) run test 2 by commenting out test 1, uncomment test 2
    c) run test 3 by commenting out test 1 & 2, uncomment test 3
*/

class User {
    protected
        $profile;

    public function __construct () {
        $this->profile = new UserProfile($this);
    }
    
    public function dispose()
    {
		$this->profile->dispose();
		$this->profile = null;
    } // end dispose();
}

class UserProfile {
    private
        $user;

    public function __construct ($user) {
        $this->user = $user;
    }
    
    public function dispose()
    {
		$this->user = null;
    } // end dispose();
}

for ($userid = 1; ; $userid++) {
	if(isset($user))
	{
		$user->dispose();
	}
    $user = new User;

    if ($userid % 100000 == 0)
        printf("memory usage after %s users: %s MB.\n",
number_format($userid), number_format(memory_get_usage() / 1024 / 1024,
2));

    continue;
}
~~~~~

In this case the result is still the same (PHP 5.3.1):

~~~~
memory usage after 100,000 users: 0.61 MB.
memory usage after 200,000 users: 0.61 MB.
memory usage after 300,000 users: 0.61 MB.
memory usage after 400,000 users: 0.61 MB.
memory usage after 500,000 users: 0.61 MB.
memory usage after 600,000 users: 0.61 MB.
memory usage after 700,000 users: 0.61 MB.
memory usage after 800,000 users: 0.61 MB.
memory usage after 900,000 users: 0.61 MB.
memory usage after 1,000,000 users: 0.61 MB.
memory usage after 1,100,000 users: 0.61 MB.
memory usage after 1,200,000 users: 0.61 MB.
~~~~

If we enable the garbage collector and remove the dispose() method, the
used memory level begins to increase, and if we call gc_collect_cycles()
after creating a new object, the used memory increases even much faster.
On my PC, it is not able to perform display even a single control
message after 100000 iterations. It stopped after approx. 33000 users:

~~~~
memory usage after 30,000 users: 25.37 MB.
memory usage after 31,000 users: 26.07 MB.
memory usage after 32,000 users: 26.76 MB.
memory usage after 33,000 users: 31.46 MB.

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to
allocate 89 bytes) in /home/me/test/memleak.php on line 17
~~~~

------------------------------------------------------------------------
[2009-12-15 01:00:00] php-bugs at lists dot php dot net

No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".

------------------------------------------------------------------------
[2009-12-08 15:23:16] nate at frickenate dot com

No change, same problem. Considering this bug hasn't even been looked at
or assigned, no surprise there.

------------------------------------------------------------------------
[2009-12-07 09:12:35] [email protected]

Please try using this snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/



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


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=48781


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=48781&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.