Bug #74792 [Ver->Csd]: Cycles created by AppendIterator not cleaned.
| From: | nikic@php.net | Date: | Wed, 09 Jun 2021 09:33:58 +0000 |
| Subject: | Bug #74792 [Ver->Csd]: Cycles created by AppendIterator not cleaned. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-234274@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74792&edit=1
ID: 74792
Updated by: nikic@php.net
Reported by: arjen at parse dot nl
Summary: Cycles created by AppendIterator not cleaned.
-Status: Verified
+Status: Closed
Type: Bug
Package: SPL related
Operating System: All
PHP Version: 7.1.6
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
I've implemented the remaining bits of GC support for SPL iterators. Relevant commits:
https://github.com/php/php-src/commit/15fafcd6648052bcbf426e4ebf60ae00a07eaaae
https://github.com/php/php-src/commit/88c57df53d5648f6e2463e7d7e7518ae23f64e28
https://github.com/php/php-src/commit/0643301c758ecf89d588db391d55a453e56b1212
(mostly undoes first commit)
https://github.com/php/php-src/commit/9c18138a71b4fdd4412cc6bcedb86a9d6115b39a
Previous Comments:
------------------------------------------------------------------------
[2021-06-08 14:35:44] nikic@php.net
Looks like this issue still exists on master.
------------------------------------------------------------------------
[2017-06-21 13:22:13] arjen at parse dot nl
Description:
------------
Cycles where an AppendIterator is involved are not collected, I guess the algorithm cannot look
inside the internal iterators.
When only using an ArrayIterator, GC works as expected.
See https://3v4l.org/BCI0F#v700
Test script:
---------------
<?php
class A
{
protected $_iterator;
protected $_appendIterator;
public function __construct($appendIterator = true)
{
$this->_appendIterator = $appendIterator;
$arrayIterator= new ArrayIterator([$this, $this, $this, $this]);
if ($appendIterator)
{
$this->_iterator = new AppendIterator();
$this->_iterator->append($arrayIterator);
}
else
{
$this->_iterator = $arrayIterator;
}
}
public function __destruct()
{
echo 'destructing A::class(' . var_export($this->_appendIterator, true) .')
' . PHP_EOL;
}
}
echo "Running with AppendIterator(): " . PHP_EOL;
$mStart = memory_get_usage();
for ($i = 0; $i < 10; $i++)
new A();
echo memory_get_usage() - $mStart . " memory increase " . PHP_EOL;
echo "Running GC.." . PHP_EOL;
echo "Found " . gc_collect_cycles() . " cycles..." . PHP_EOL . PHP_EOL;
echo "Running without AppendIterator(): " . PHP_EOL;
$mStart = memory_get_usage();
for ($i = 0; $i < 10; $i++)
new A(false);
echo memory_get_usage() - $mStart . " memory increase " . PHP_EOL;
echo "Running GC.." . PHP_EOL;
echo "Found " . gc_collect_cycles() . " cycles..." . PHP_EOL;
echo "Done!" . PHP_EOL . PHP_EOL;
Expected result:
----------------
Cycles also collected when AppendIterator is between A->iterator and ArrayIterator.
Actual result:
--------------
No cycles found
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74792&edit=1