类 中匿名函数的内存泄漏?

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().

来强制执行此操作