如果我有循环引用,是否可以触发PHP垃圾回收自动发生? [英] Can I trigger PHP garbage collection to happen automatically if I have circular references?
问题描述
我似乎想起了一种为类设置 __ destruct
的方法,它可以确保一旦外部对象立即清除循环引用超出范围。然而,我建立的简单测试似乎表明,这不是我预期/希望的行为。
有没有一种方法来设置我的类,以这种方式当最外层的对象超出范围时,PHP会正确地清理它们?
我不想寻找替代方法来编写这段代码,我正在寻找是否这个可以做到,如果是的话,怎么样?我一般尽可能避免使用这些类型的循环引用。
class Bar {
private $ foo;
public function __construct($ foo){
$ this-> foo = $ foo;
public function __destruct(){
print[destroying bar] \\\
;
unset($ this-> foo);
}
}
class Foo {
private $ bar;
public function __construct(){
$ this-> bar = new Bar($ this);
}
public function __destruct(){
print[destroying foo] \\\
;
unset($ this-> bar);
函数testGarbageCollection(){
$ foo = new Foo();
}
($ i = 0; $ i <25; $ i ++){
echo memory_get_usage()。 \\\
;
testGarbageCollection();
}
输出如下所示:
60440
61504
62036
62564
63092
63620
[销毁foo]
[销毁条]
[销毁foo]
[销毁条]
[销毁foo]
[销毁条]
[销毁foo]
[销毁条]
[销毁foo]
[销毁条]
什么我曾希望:
60440
[destorying foo]
[destorying bar]
60440
[destorying foo]
[destorying bar]
60440
[destorying foo]
[destorying bar]
60440
[destorying foo ]
[destorying bar]
60440
[destorying foo]
[destorying bar]
60440
[destorying foo]
[destorying bar ]
更新:
<>有关PHP> 5.3的这个问题有几个很好的答案,但是我选择了适用于PHP的答案5.3,因为它实际上与我的项目(PHP 5.2.x)有关。
class Foo {
private $ bar;
public function __construct(){
$ this-> bar = new Bar($ this);
public function cleanup(){
$ this-> bar = null;
}
public function __destruct(){
print[destroying foo] \\\
;
}
}
class Bar {
private $ foo;
public function __construct($ foo){
$ this-> foo = $ foo;
public function __destruct(){
print[destroying bar] \\\
;
函数testGarbageCollection(){
$ foo = new Foo();
$ foo-> cleanup();
}
我不确定这是多么有用,但这是您唯一的选择< 5.3
I seem to recall a way to setup the __destruct
for a class in such a way that it would ensure that circular references would be cleaned up as soon as the outside object falls out of scope. However, the simple test I built seems to indicate that this is not behaving as I had expected/hoped.
Is there a way to setup my classes in such a way that PHP would clean them up correctly when the outermost object falls out of scope?
I am not looking for alternate ways to write this code, I am looking for whether or not this can be done, and if so, how? I generally try to avoid these types of circular references where possible.
class Bar {
private $foo;
public function __construct($foo) {
$this->foo = $foo;
}
public function __destruct() {
print "[destroying bar]\n";
unset($this->foo);
}
}
class Foo {
private $bar;
public function __construct() {
$this->bar = new Bar($this);
}
public function __destruct() {
print "[destroying foo]\n";
unset($this->bar);
}
}
function testGarbageCollection() {
$foo = new Foo();
}
for ( $i = 0; $i < 25; $i++ ) {
echo memory_get_usage() . "\n";
testGarbageCollection();
}
The output looks like this:
60440
61504
62036
62564
63092
63620
[ destroying foo ]
[ destroying bar ]
[ destroying foo ]
[ destroying bar ]
[ destroying foo ]
[ destroying bar ]
[ destroying foo ]
[ destroying bar ]
[ destroying foo ]
[ destroying bar ]
What I had hoped for:
60440
[ destorying foo ]
[ destorying bar ]
60440
[ destorying foo ]
[ destorying bar ]
60440
[ destorying foo ]
[ destorying bar ]
60440
[ destorying foo ]
[ destorying bar ]
60440
[ destorying foo ]
[ destorying bar ]
60440
[ destorying foo ]
[ destorying bar ]
UPDATE:
There are several great answers to this question relating to PHP > 5.3, but I selected the answer that would work with PHP < 5.3 since it actually relates to my project ( PHP 5.2.x ).
As __destruct
is only called once the object is being reclaimed, you can't use it for that. You can create a manual cleanup function though:
class Foo {
private $bar;
public function __construct() {
$this->bar = new Bar($this);
}
public function cleanup() {
$this->bar = null;
}
public function __destruct() {
print "[destroying foo]\n";
}
}
class Bar {
private $foo;
public function __construct($foo) {
$this->foo = $foo;
}
public function __destruct() {
print "[destroying bar]\n";
}
}
function testGarbageCollection() {
$foo = new Foo();
$foo->cleanup();
}
I'm not sure how useful this is, but that's really your only option < 5.3
这篇关于如果我有循环引用,是否可以触发PHP垃圾回收自动发生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!