Bug #78933 [Fbk]: Presence of a destructor affects garbage collection
| From: | requinix@php.net | Date: | Sun, 08 Dec 2019 22:12:54 +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-224148@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: requinix@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:
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?
Previous Comments:
------------------------------------------------------------------------
[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