[php-src] Issue #7958: `LimitIterator` is not GCable
| From: | iluuu1994 | Date: | Thu, 03 Feb 2022 15:13:45 +0000 |
| Subject: | [php-src] Issue #7958: `LimitIterator` is not GCable | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-239441@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/7958
Comment Author: iluuu1994
Doesn't seem like this is caused by
afab9eb48c883766b7870f76f2e2b0a4bd575786. In
fact, it fixes the second iteration in your example, which also leaked.
Here's a somewhat condensed example:
```php
class Action
{
public \Iterator $iterator;
public function __construct(array $data)
{
$this->iterator = new ArrayIterator($data);
echo '-- c ' . spl_object_id($this) . "\n";
}
public function __destruct()
{
echo '-- d ' . spl_object_id($this) . "\n";
}
public function filter()
{
$this->iterator = new \CallbackFilterIterator($this->iterator, fn() => true);
$this->iterator->rewind();
}
}
$action = new Action(['a', 'b']);
$action->filter();
$action->filter();
print_r(iterator_to_array($action->iterator));
$action = null;
gc_collect_cycles();
```
```log
-- c 1
Array
(
[0] => a
[1] => b
)
===DONE===
-- d 1
[Thu Feb 3 15:51:02 2022] Script: './ext/spl/tests/bug-gh7958.php'
./Zend/zend_closures.c(505) : Freeing 0x00007f5edee6b900 (328 bytes),
script=./ext/spl/tests/bug-gh7958.php
[Thu Feb 3 15:51:02 2022] Script: './ext/spl/tests/bug-gh7958.php'
./Zend/zend_objects_API.h(92) : Freeing 0x00007f5edee84540 (176 bytes),
script=./ext/spl/tests/bug-gh7958.php
[Thu Feb 3 15:51:02 2022] Script: './ext/spl/tests/bug-gh7958.php'
./Zend/zend_interfaces.c(206) : Freeing 0x00007f5edee87280 (112 bytes),
script=./ext/spl/tests/bug-gh7958.php
=== Total 3 memory leaks detected ===
```
It's caused by the reference to $this from the CallbackFilterIterator
closure. Making the closure static solves the issue. It only happens for nested
CallbackFilterIterator iterators.