代码之家  ›  专栏  ›  技术社区  ›  martin.malek

PHP内存泄漏和分叉

  •  3
  • martin.malek  · 技术社区  · 15 年前

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

    $obj = NULL;
    unset($obj);
    

    但这仍然没有帮助。

    我的问题是,当我分叉进程,对象将在子线程中被创建和销毁时会发生什么?这会是一样的吗? 或者有其他的方法来释放记忆吗?

    这是导入脚本,它将消耗很少的内存。

    3 回复  |  直到 15 年前
        1
  •  12
  •   NSSec    15 年前

    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   
    
        2
  •  5
  •   Amber    15 年前

    调用前无需将变量设置为空。 unset() 关于它。但是请注意,unset()不会强制释放内存。您可能要检查的主要问题是,您的对象清除了所有引用 必须先处理大量数据才能取消设置。

        3
  •  1
  •   Quamis    15 年前

    好吧,您的导入脚本一开始不应该使用几Gigs的RAM。当您完全不需要时,尝试将大块数据存储在另一个地方(文件系统或数据库)。也可以考虑一次导入较小的部分,而不是全部导入到一个大的块中,即使这需要更长的时间来处理,但是这样做会抵消大量的内存消耗。

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