2009-09-03 61 views
3

我试图避免PHP中的内存泄漏。当我创建一个对象并最终取消它时,它仍然在内存中。未设置看起来像:PHP内存泄漏和叉

$obj = NULL; 
unset($obj); 

仍然这不会帮助。

我的问题是什么时候会发生什么时,我分叉的进程和对象将被创建并在子线程中被破坏?这是否一样? 或者有没有其他方式如何释放内存?

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

回答

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 
+0

+1,很好的示例数据 – 2009-09-03 09:01:41

5

在调用unset()之前,不需要将变量设置为NULL。请注意,unset()不会强制释放内存。您可能希望检查的主要内容是您的对象清除任何引用必须在您取消设置之前对大量数据进行清除。

1

以及您导入脚本不应该摆在首位使用RAM的一些演出。尝试将大块数据存储在另一个地方(文件系统或数据库),当你不需要它时。同时考虑一次导入较小的部分,即使需要较长的时间处理,也不是全部都在一个大块中,但这样您就可以权衡大内存消耗。

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