Bug #74792 [Ver->Csd]: Cycles created by AppendIterator not cleaned.

From: 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

« previous php.bugs (#234274) next »