类 中匿名函数的内存泄漏?
memory leak with anonymous functions in classes?
这是我的代码:
class a
{
public function __construct()
{
$this->test = function() {};
}
public function __destruct()
{
echo "called\n";
}
}
while (true) {
$a = new a;
$new = memory_get_usage();
if (isset($old)) {
echo ($new - $old) . "\n";
}
$old = $new;
}
每次循环运行时使用该代码会额外消耗 736 字节的内存。原因是对象的析构函数从未被调用。
如果我将 $a = new a;
替换为 $a = function() {};
,那么每次循环都不会消耗额外的内存,而且每次都会调用构造函数。
如果我将 $this->test = function() {};
替换为 $this->test = WeakReference::create(function() {});
这似乎可以解决问题,但我必须重写所有代码才能执行 $this->test->get()(...)
而不是 ($this->test)('...')
或类似的东西。
是否有另一种方法来堵住这个内存泄漏,它需要比 WeakReferences 更少的重写?
在结束循环之前尝试gc_collect_cycles();
。
当你有普通引用时,你正在创建一个循环引用,因为对象有一个对函数的引用,而函数是一个引用对象范围的闭包。循环引用是基于引用计数的垃圾收集的一个问题,因此在重新分配变量时不会立即回收内存。
完整垃圾收集器将定期回收对象和函数。您可以通过调用 gc_collect_cycles()
.
来强制执行此操作
这是我的代码:
class a
{
public function __construct()
{
$this->test = function() {};
}
public function __destruct()
{
echo "called\n";
}
}
while (true) {
$a = new a;
$new = memory_get_usage();
if (isset($old)) {
echo ($new - $old) . "\n";
}
$old = $new;
}
每次循环运行时使用该代码会额外消耗 736 字节的内存。原因是对象的析构函数从未被调用。
如果我将 $a = new a;
替换为 $a = function() {};
,那么每次循环都不会消耗额外的内存,而且每次都会调用构造函数。
如果我将 $this->test = function() {};
替换为 $this->test = WeakReference::create(function() {});
这似乎可以解决问题,但我必须重写所有代码才能执行 $this->test->get()(...)
而不是 ($this->test)('...')
或类似的东西。
是否有另一种方法来堵住这个内存泄漏,它需要比 WeakReferences 更少的重写?
在结束循环之前尝试gc_collect_cycles();
。
当你有普通引用时,你正在创建一个循环引用,因为对象有一个对函数的引用,而函数是一个引用对象范围的闭包。循环引用是基于引用计数的垃圾收集的一个问题,因此在重新分配变量时不会立即回收内存。
完整垃圾收集器将定期回收对象和函数。您可以通过调用 gc_collect_cycles()
.