php - PHP 何时在长时间运行的脚本中运行垃圾收集?

标签 php garbage-collection

我正在编写一个 PHP cli 程序,它是队列系统的工作进程。

我假设 PHP 在这种情况下会不时收集垃圾,并且不会经常达到内存限制。

情况似乎并非如此。

笔记

  • 在 PHP 7 上运行
  • 它是一个长期运行的脚本
  • zend.enable_gc = 1
  • 没有全局变量
  • 最佳答案

    归结为这一点。您必须通过调用 gc_collect_cycles() 手动触发垃圾回收。 .

    我已经编写了一堆代码来尝试跟踪它并归结为两个脚本:

    这个不会崩溃:

    for($i = 0;$i < 100;$i++) {
        useMemory();
        gc_collect_cycles();
    }
    

    这个崩溃了:
    for($i = 0;$i < 100;$i++) {
        useMemory();
    }
    

    这是在 Blackfire 上比较这些脚本的链接

    如您所见,当您不调用 gc_collect_cycles它永远不会发生,并且您达到了内存限制,并且 PHP 会杀死自己。

    PHP 甚至没有利用这个机会进行 GC 本身。这背后的原因在 PHP-DEV mailing list 上进行了讨论。 , 但基本上归结为如何运行 __destruct 的复杂性达到内存限制时需要内存的方法。 (也在错误跟踪器 #60982 上)。

    内存使用函数:

    这是我用来“浪费”内存的代码,它有目的地创建只能由垃圾收集器清理的循环引用。请注意,如果没有这些循环,一旦对象超出范围,就会通过引用计数来清理它们。
    class Big {
        private $data;
        public function __construct($d = 0) {
            for($i = 0;$i< 1024 * 10;$i++) {
                $this->$i = chr(rand(97, 122));
            }
        }
    }
    
    function useMemory() {
        $a = new Big();
        $b = new Big();
    
        $a->b = $b;
        $b->a = $a;
    }
    

    关于php - PHP 何时在长时间运行的脚本中运行垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38850391/

    相关文章:

    php - 如何解决phpmyadmin fatal error ?

    javascript - 如何使用服务器端 php (Laravel) 加载其他网站,例如 Hypothes.is 或 ProjectHuddle?

    java - 垃圾收集器在没有用户代码运行的情况下在 Tomcat Web 应用程序中频繁运行

    c# - 量化垃圾收集与显式内存管理的性能

    java - GC 和在 for 循环中赋值

    php - PropertyAccessor 需要对象或数组的图形来操作,但它发现类型 "NULL"

    php - 如何添加选择不同?

    javascript - 通过 Javascript WeakMaps 收集垃圾的缓存

    java - 什么-XX :-PrintGC and XX:-PrintGCDetails flags do?

    php - 替换数组值以增加