【问题标题】:PHP memory leak and forkPHP 内存泄漏和分叉
【发布时间】:2023-03-16 18:32:01
【问题描述】:

我试图避免 PHP 中的内存泄漏。当我创建一个对象并在最后取消设置它时,它仍在内存中。未设置的样子:

$obj = NULL;
unset($obj);

这仍然无济于事。

我的问题是当我分叉进程并且对象将在子线程中创建和销毁时会发生什么?这会一样吗? 或者有没有其他方法可以释放内存?

这是导入脚本,将消耗少量内存。

【问题讨论】:

    标签: php memory-leaks


    【解决方案1】:

    首先,您的导入脚本不应该使用几场 ram。当您绝对不需要时,尝试将大块数据存储在另一个地方(文件系统或数据库)。还可以考虑一次导入较小的部分,而不是全部导入一大块,即使处理时间会更长,但这样可以权衡大内存消耗。

    您所说的不是内存泄漏,因为这是有据可查的众所周知的行为。正如 MathieuK 所说,在 PHP5.3 中您可能会使用一些 gc* 函数,但我从未测试过它们。 PHP 是一种用于处理临时大块数据的非常糟糕的语言,因为在分配之后,分配的内存将永远不会再被释放,即使您取消设置它(这是因为分配的内存将被重用,而这在网页中是一件好事,但在大型“硬核”脚本中不是一件好事..)。

    【讨论】:

      【解决方案2】:

      PHP 5.3 有一个可以收集循环引用的垃圾收集器。值得一试:

      gc_enable();
      
      class A {
        public function __construct() {
          $this->data = str_repeat("A", 1024000);
        }
      }
      
      $mem = memory_get_usage();
      $a = new A();
      $mem2 = memory_get_usage();
      $a->a = $a;
      $a->a->mydata =  $a->data . 'test';
      $mem3 = memory_get_usage();
      unset($a);
      gc_collect_cycles();
      $mem4 = memory_get_usage();      
      
      printf("MEM 1 at start %0.2f Mb\n", ($mem / 1024) / 1024);
      printf("MEM 2 after first instantiation %0.2f Mb\n", ($mem2 / 1024) / 1024);
      printf("MEM 3 after self-ref: %0.2f Mb\n", ($mem3 / 1024) / 1024);
      printf("MEM 4 after unset(\$a): %0.2f Mb\n", ($mem4 / 1024) / 1024);      
      

      输出:

      MEM 1 at start: 0.31 Mb
      MEM 2 after first instantiation: 1.29 Mb
      MEM 3 after self-ref: 2.26 Mb
      MEM 4 after unset($a): 0.31 Mb   
      

      【讨论】:

        【解决方案3】:

        在调用unset() 之前无需将变量设置为NULL。但是请注意, unset() 不会强制释放内存。您可能要检查的主要内容是您的对象在取消设置之前清除了对大块数据的所有引用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-10
          • 2023-03-17
          • 2012-04-17
          • 2012-01-12
          • 2017-01-28
          相关资源
          最近更新 更多