On 22/01/2022 15:30, Christoph M. Becker wrote:
If you trigger the garbage collector manually (i.e. call gc_collect_cycles() after unset($callback)), the loop terminates right away. I'm not sure why it doesn't without manually triggering the GC.
Most values are freed as soon as their refcount reaches zero, which obviously won't happen for circular references, so an additional algorithm is needed for those. This "cycle collection" algorithm is relatively expensive, so doesn't run every time a possible candidate is found, but only when a list of candidates reaches a particular threshold. The algorithm is outlined in the manual, although it looks like the constant 10000 mentioned there has been replaced by an adaptive threshold (which can be inspected with gc_status()): https://www.php.net/manual/en/features.gc.collecting-cycles.php
If you measure memory usage while running the example code in a loop, you should see it slowly growing and then periodically dropping each time a cycle collection is run. That's why gc_collect_cycles() exists - if you _know_ you've created circular references, you can tell the engine to find and free them immediately, rather than waiting for the next pass.
Regards, -- Rowan Tommins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php