这涉及一个 PHP 5.3 Cli 应用程序,该应用程序以复杂的方式处理大量数据,需要数小时才能运行。有人发现,关闭垃圾收集可以使它运行得更快(可能高达 50%)。
我遇到的唯一一篇提到此性能影响的文章是 http://derickrethans.nl/collecting-garbage-performance-considerations.html .我不确定我是否完全遵循它,但它似乎表明它仅适用于具有大量循环引用的代码。
请问有人能解释一下吗?
另外,既然我们已经关闭了gc,有没有办法手动减少内存?建议使用 unset()。快速测试表明,无论对象的大小如何,unset() 都会释放大约 80 个字节。这表明它只是取消了引用,我在网上阅读的内容证实了这一点。我认为当变量超出范围时,即使没有垃圾收集,这八十个字节无论如何都会被释放,我的想法是否正确?
最佳答案
您刚刚禁用了循环引用 GC。常规的仍然有效。
常见的 GC 测试,无论是否有 zval
(“内存”),不再被任何变量或属性引用,并将释放此内存。循环引用是指两个或多个对象直接或间接相互引用
$a = new stdClass;
$b = new stdClass;
$a->b = $b;
$b->a = $a;
unset($a, $b);
现在两个对象相互引用,但它们都没有被其他任何地方引用,所以它们是不可访问的。这就是循环引用 GC 试图检测的内容,但为了找到它们,它遍历每个已知对象并找出是否存在“来自外部”的引用。它有点复杂,但仅此而已;)因此在具有许多引用的结构中,尤其是循环引用的结构中,这是一项艰巨的任务。
值得一提的是:使用unset()
,您只能删除引用,但不能(直接)释放内存。这是稍后由 GC 完成的(它做得很好 :))
关于php - 为什么 PHP 的垃圾收集器会降低性能,没有它如何管理内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14501415/