php - 为什么 PHP 的垃圾收集器会降低性能,没有它如何管理内存?

标签 php memory-management garbage-collection unset

这涉及一个 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/

相关文章:

php - MySQL DATETIME 格式比较 - 是否需要 strtotime?

c# - 类中声明的变量的内存分配

c# - 如何列出 GC finalization 列表中的所有对象?

php - 使用 jquery 在父标签之外附加 html

php - 在<select>中获取日期、分解、使用数据选择选项

ios - 代码 : Working In ARC and NSArrays

c# - 在 Dispose(bool) 方法实现中,不应该将成员设置为 null 吗?

java - 从 Java 6 迁移到 Java 7 期间会发生什么

garbage-collection - 我可以在性能监视器中使用哪个计数器来查看有多少内存正在等待 GC?

文件上传超过 8MB 时出现 PHP ERR_CONNECTION_RESET 错误