php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #60139 Anonymous functions create cycles not detected by the GC
Submitted: 2011-10-26 10:36 UTC Modified: 2011-11-02 06:31 UTC
From: lbarnaud@php.net Assigned: dmitry
Status: Closed Package: Performance problem
PHP Version: 5.4.0beta2 OS:
Private report: No CVE-ID:
 [2011-10-26 10:36 UTC] lbarnaud@php.net
Description:
------------
In the following Script 1 and Script 2, the created objects are not destructed until the engine shutdowns because of a reference cycle.

The objects hold a reference to an anonymous function that itself hold a reference to the object.

It seems that the garbage collector is unable to break the cycle.

Script 3 doesn't leak memory because the anonymous function doesn't hold a reference to the object.

Test script:
---------------
# Script 1 (leaks with php5.4)

<?php

class Foo
{
    public $x;

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

echo memory_get_usage(), "\n";

for ($i = 0; $i < 1000; ++$i) {
    new Foo;
}
gc_collect_cycles();

echo memory_get_usage(), "\n";
?>

# Script 2 (leaks with php5.3)

<?php

class Foo
{
    public $x;

    public function __construct() {
        $self = $this;
        $this->x = function() use ($self) {};
    }
}

echo memory_get_usage(), "\n";

for ($i = 0; $i < 1000; ++$i) {
    new Foo;
}
gc_collect_cycles();

echo memory_get_usage(), "\n";

?>

# Script 3 (no leak)

<?php

class Foo
{
    public $x;

    public function __construct() {
        $this->x = get_fun();
    }
}

function get_fun() {
    return function() {};
}

echo memory_get_usage(), "\n";

for ($i = 0; $i < 1000; ++$i) {
    new Foo;
}
gc_collect_cycles();

echo memory_get_usage(), "\n";
?>

Expected result:
----------------
Memory usage before and after is approximatel the same:

121040
121152

Actual result:
--------------
Objects are never freed and memory usage increases:

120724
417640

Patches

gc-closure2.diff (last revision 2011-10-31 11:04 UTC) by dmitry@php.net)
gc-closure.diff (last revision 2011-10-31 11:04 UTC) by dmitry@php.net)
bug60139.php5.4.diff (last revision 2011-10-29 10:23 UTC) by arnaud dot lb at gmail dot com)
test2.phpt (last revision 2011-10-28 14:24 UTC) by arnaud dot lb at gmail dot com)
test1.phpt (last revision 2011-10-28 14:23 UTC) by arnaud dot lb at gmail dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-10-31 08:19 UTC] dmitry@php.net
-Assigned To: +Assigned To: dmitry
 [2011-10-31 08:44 UTC] dmitry@php.net
The following patch has been added/updated:

Patch Name: gc-closure.diff
Revision:   1320050649
URL:        https://bugs.php.net/patch-display.php?bug=60139&patch=gc-closure.diff&revision=1320050649
 [2011-10-31 11:04 UTC] dmitry@php.net
The following patch has been added/updated:

Patch Name: gc-closure.diff
Revision:   1320059056
URL:        https://bugs.php.net/patch-display.php?bug=60139&patch=gc-closure.diff&revision=1320059056
 [2011-10-31 11:04 UTC] dmitry@php.net
The following patch has been added/updated:

Patch Name: gc-closure2.diff
Revision:   1320059088
URL:        https://bugs.php.net/patch-display.php?bug=60139&patch=gc-closure2.diff&revision=1320059088
 [2011-11-02 06:31 UTC] dmitry@php.net
Automatic comment from SVN on behalf of dmitry
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=318671
Log: Fixed bug #60139 (Anonymous functions create cycles not detected by the GC)
 [2011-11-02 06:31 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2011-11-02 06:31 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2012-04-18 09:48 UTC] laruence@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b64e91ddebdb0c33d7b6bf4dc93aae39308e67ce
Log: Fixed bug #60139 (Anonymous functions create cycles not detected by the GC)
 [2012-07-24 23:39 UTC] rasmus@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b64e91ddebdb0c33d7b6bf4dc93aae39308e67ce
Log: Fixed bug #60139 (Anonymous functions create cycles not detected by the GC)
 [2013-11-17 09:35 UTC] laruence@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b64e91ddebdb0c33d7b6bf4dc93aae39308e67ce
Log: Fixed bug #60139 (Anonymous functions create cycles not detected by the GC)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 13:02:15 2014 UTC