为什么PHP的垃圾收集器会降低性能,以及如何在没有它的情况下管理内存?

nao*_*omi 7 php garbage-collection memory-management unset

这与PHP 5.3 Cli应用程序有关,该应用程序以复杂的方式处理大量数据,需要数小时才能运行.有人发现关闭垃圾收集使其运行速度更快(可能高达50%).

我遇到的唯一提到这种性能影响的文章是http://derickrethans.nl/collecting-garbage-performance-considerations.html.我不确定我是否完全遵循它,但它似乎表明它只适用于具有大量循环引用的代码.

有人可以对此有所了解吗?

另外,鉴于我们已关闭gc,有没有办法手动减少内存?建议使用unset().快速测试表明,无论对象的大小如何,unset()都会释放80个左右的字节.这表明它只是取消了参考,这是我在网上看到的.我是否正确地认为,当变量超出范围时,即使没有垃圾收集,这些80个字节也会被释放?

Kin*_*nch 5

您刚刚禁用了循环引用 GC。常规的仍然有效。

常见的GC测试,无论是否有zvals(“内存”),不再被任何变量或属性引用,都会释放该内存。循环引用是指两个或多个对象直接或间接相互引用

$a = new stdClass;
$b = new stdClass;
$a->b = $b;
$b->a = $a;
unset($a, $b);
Run Code Online (Sandbox Code Playgroud)

现在两个对象都互相引用,但它们都没有从其他任何地方引用,因此它们是不可访问的。这就是循环引用 GC 试图检测的内容,但为了找到它们,它会迭代每个已知对象并找出是否存在“来自外部”的引用。它有点复杂,但简化了就是这样;)因此,在具有许多引用的结构中,尤其是圆形引用的结构中,这是一项艰巨的任务。

值得一提的是:unset()您只删除引用,但不释放内存(直接)。这是稍后由 GC 完成的(而且做得很好:))