PHP内存泄漏和fork

3

我想避免PHP中的内存泄漏。当我创建一个对象并在结尾处取消设置时,它仍然存在于内存中。取消设置的代码如下:

$obj = NULL;
unset($obj);

但这并不能解决问题。

我的问题是,当我分叉进程并在子线程中创建和销毁对象时,会发生什么?这样做会有什么不同吗? 或者还有其他方法来释放内存吗?

这是一个将消耗几个G内存的重要脚本。

3个回答

12

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   

5
不需要在调用unset()之前将变量设置为NULL。但请注意,unset()不会强制释放内存。您可能希望检查的主要事情是,在取消设置之前,对象是否清除了对大块数据的任何引用。请注意保留HTML标记。

1

好的,你的导入脚本一开始不应该使用几个G的内存。当你不绝对需要它时,尽量将大块数据存储在另一个地方(文件系统或数据库)中。同时考虑分批次导入较小的部分,而不是一次性全部导入,即使处理时间会更长,但这样可以权衡大内存消耗。

你所说的并不是内存泄漏,因为这是一种已记录并知名的行为。如MathieuK所说,在PHP5.3中,您可以使用一些gc*函数,但我从未测试过。PHP是一种非常糟糕的语言,用于处理临时大块数据,因为在分配后,即使您取消设置(这是因为分配的内存将被重用,这在Web页面中是个好事,但在大型“硬核”脚本中却不是好事),分配的内存也永远不会被释放。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接