Bug #75914 [Com]: Memory leak when anonymous function is assigned to the class variable
| From: | john357smith at gmail dot com | Date: | Sun, 04 Feb 2018 16:51:13 +0000 |
| Subject: | Bug #75914 [Com]: Memory leak when anonymous function is assigned to the class variable | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-213805@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75914&edit=1
ID: 75914
Comment by: john357smith at gmail dot com
Reported by: john357smith at gmail dot com
Summary: Memory leak when anonymous function is assigned to
the class variable
Status: Not a bug
Type: Bug
Package: Performance problem
Operating System: Linux
PHP Version: 7.2.2
Block user comment: N
Private report: N
New Comment:
OK I see, thanks for an explanation.
Previous Comments:
------------------------------------------------------------------------
[2018-02-04 16:10:02] nikic@php.net
The closure contains an implicit reference to $this. You can avoid creating the cycle by using a
static closure:
$this->class_var = static function() { };
Of course, this will only work if your closure does not require access to $this.
------------------------------------------------------------------------
[2018-02-04 16:06:16] john357smith at gmail dot com
Where in this example is defined circular reference? Anonymous function is empty and has no
references anywhere. I'm aware that it is possible after "some" time a GC will free
it but the problem is this is only the smallest example. The class could be (and in fact it is) much
bigger in memory which leads for me to memory limit exceeded error.
------------------------------------------------------------------------
[2018-02-04 15:47:37] kelunik@php.net
There's no leak. You're creating a circular reference there. If you use
gc_collect_cycles(), everything is fine.
If you remove the usleep(), you'll see that it runs totally fine even without
gc_collect_cycles(). It just takes its time until the GC kicks in.
------------------------------------------------------------------------
[2018-02-04 14:04:22] john357smith at gmail dot com
Description:
------------
In case an anonymous function is assigned to the class variable (doesn't matter if public,
private or protected) and a new class instance is created a memory is not freed at the end. To
correctly free memory you have to set a class variable to null or call a garbage collector manually.
See test script.
Test script:
---------------
class TestMem
{
public $class_var = null;
public function __construct()
{
$this->class_var = function() { };
}
}
while (true)
{
$frame = new TestMem();
//$frame->class_var = null;
//echo(gc_collect_cycles()."\n");
echo(memory_get_usage()."\n");
usleep(10000);
}
Expected result:
----------------
A memory usage is still on the same level.
Actual result:
--------------
A memory usage is constantly increasing.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75914&edit=1