Bug #78933 [Fbk]: Presence of a destructor affects garbage collection

From: Date: Mon, 09 Dec 2019 07:56:26 +0000
Subject: Bug #78933 [Fbk]: Presence of a destructor affects garbage collection
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-224150@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78933&edit=1 ID: 78933 Updated by: nikic@php.net Reported by: requinix@php.net Summary: Presence of a destructor affects garbage collection Status: Feedback Type: Bug Package: *General Issues Operating System: Any (Windows?) PHP Version: 7.4.0 Block user comment: N Private report: N New Comment: Assuming the destructor doesn't do anything to make the object non-GCable, I believe that two runs should be sufficient. > Or perhaps a new optional "bool $repeat = true" argument to do that automatically? In reference to the original issue with PDO SQLite: No, I don't think this makes sense. Generally, manual GC runs should not be necessary to influence program behavior. I think this is an indication that PDO needs a way to explicitly close a connection that does not require destroying the object. I believe this was rejected in the past "because you can just write unset($pdo)", but in the presence of circular references this just isn't reliable. Previous Comments: ------------------------------------------------------------------------ [2019-12-08 22:12:54] requinix@php.net Yes it does. Could it ever need more than two? If so, that would suggest using it like while (gc_collect_cycles()); Or perhaps a new optional "bool $repeat = true" argument to do that automatically? ------------------------------------------------------------------------ [2019-12-08 22:05:32] nikic@php.net Classes with destructors may require two GC runs to be fully collected. Does it work if you repeat gc_collect_cycles() twice? ------------------------------------------------------------------------ [2019-12-08 21:56:37] requinix@php.net Related To: Bug #78930 ------------------------------------------------------------------------ [2019-12-08 21:55:34] requinix@php.net Description: ------------ Discovered during bug #78930. Works in PHP 7.3. With two classes forming a cyclic reference, one of them doesn't seem to be GCed properly if the other has a destructor - even if empty. It works without the destructor. The only way I've been able to reproduce *and detect* the problem has been to use ext/pdo_sqlite to open a file, then test that the file is closed using unlink(). As far as I know, this is only possible to do on Windows since Linux is supposed to allow deleting files with open handles. But this doesn't quite feel like a PDO, SQLite, or Windows issue. I assume the GC recognizes when there is a destructor that needs to be invoked, and that affects how it cleans up. Test script: --------------- <?php class Test { public $base; public $container; public function __construct(Container $c) { $this->container = $c; $this->base = new PDO("sqlite:base.sqlite", "", ""); } } class Container { public $test; public function __construct() { $this->test = new Test($this); } // commented: no errors, file deleted // uncommented: "resource temporarily unavailable", file not deleted function __destruct() { } } new Container(); gc_collect_cycles(); unlink("base.sqlite"); ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78933&edit=1

« previous php.bugs (#224150) next »