Bug #68132 [Com]: Memory leakage while using anonymous functions
| From: | nikic@php.net | Date: | Fri, 03 Oct 2014 20:38:53 +0000 |
| Subject: | Bug #68132 [Com]: Memory leakage while using anonymous functions | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-187833@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=68132&edit=1
ID: 68132
Comment by: nikic@php.net
Reported by: nikola at petkanski dot com
Summary: Memory leakage while using anonymous functions
Status: Not a bug
Type: Bug
Package: Performance problem
Operating System: Linux
PHP Version: 5.4.33
Block user comment: N
Private report: N
New Comment:
More accurate calculation: (1220536-237296)/((16384-1024)*8*8) == 1.0002, where 1024 is the initial
object store size.
Previous Comments:
------------------------------------------------------------------------
[2014-10-03 20:36:51] nikic@php.net
There is no real leak here - which is easy to see if you adjust the the number of iterations. The
memory usage will stay the same.
What you see are retained object store buckets, see https://bugs.php.net/bug.php?id=33487. The GC runs
once the root buffer with 10k elements fills up, at which point the object store uses 2^14 buckets.
You can see that this is about right, because (1220536-237296)/(16384*8*8) == 0.93 (8*8 is the size
of an object store bucket).
In PHP 7 the memory difference will be 8 times smaller, so it doesn't really matter anymore.
------------------------------------------------------------------------
[2014-10-02 13:55:39] nikola at petkanski dot com
Description:
------------
This bug seem like a duplicate of an earlier one that got marked as fixed:
- https://bugs.php.net/bug.php?id=60139
It has been tried on the following configurations and the problem persists:
PHP 5.4.32 (cli) (built: Aug 22 2014 07:07:38)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
PHP 5.5.9-1ubuntu4.4 (cli) (built: Sep 4 2014 06:56:34)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
For convenience I'm gonna copy the description of the original bug as it seem relevant and I
guess the problem is the same:
-----
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)
<?php
class Foo
{
public $x;
public function __construct() {
$this->x = function() {};
}
}
echo memory_get_usage(), "\n";
for ($i = 0; $i < 100000; ++$i) {
new Foo;
}
gc_collect_cycles();
echo memory_get_usage(), "\n";
?>
# Script 2 (leaks)
<?php
class Foo
{
public $x;
public function __construct() {
$self = $this;
$this->x = function() use ($self) {};
}
}
echo memory_get_usage(), "\n";
for ($i = 0; $i < 100000; ++$i) {
new Foo;
}
gc_collect_cycles();
echo memory_get_usage(), "\n";
?>
# Script 3 (does not 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 approximately the same:
nikola@nikola-450G1:~$ php script3.php
237944
238152
Actual result:
--------------
Objects are never freed and memory usage increases:
nikola@nikola-450G1:~$ php script1.php
237296
1220536
nikola@nikola-450G1:~$ php script2.php
237848
1221256
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68132&edit=1