我想避免PHP中的内存泄漏。当我创建一个对象并在结尾处取消设置时,它仍然存在于内存中。取消设置的代码如下:
$obj = NULL;
unset($obj);
但这并不能解决问题。
我的问题是,当我分叉进程并在子线程中创建和销毁对象时,会发生什么?这样做会有什么不同吗? 或者还有其他方法来释放内存吗?
这是一个将消耗几个G内存的重要脚本。
我想避免PHP中的内存泄漏。当我创建一个对象并在结尾处取消设置时,它仍然存在于内存中。取消设置的代码如下:
$obj = NULL;
unset($obj);
但这并不能解决问题。
我的问题是,当我分叉进程并在子线程中创建和销毁对象时,会发生什么?这样做会有什么不同吗? 或者还有其他方法来释放内存吗?
这是一个将消耗几个G内存的重要脚本。
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
unset()
之前将变量设置为NULL。但请注意,unset()不会强制释放内存。您可能希望检查的主要事情是,在取消设置之前,对象是否清除了对大块数据的任何引用。请注意保留HTML标记。好的,你的导入脚本一开始不应该使用几个G的内存。当你不绝对需要它时,尽量将大块数据存储在另一个地方(文件系统或数据库)中。同时考虑分批次导入较小的部分,而不是一次性全部导入,即使处理时间会更长,但这样可以权衡大内存消耗。
你所说的并不是内存泄漏,因为这是一种已记录并知名的行为。如MathieuK所说,在PHP5.3中,您可以使用一些gc*函数,但我从未测试过。PHP是一种非常糟糕的语言,用于处理临时大块数据,因为在分配后,即使您取消设置(这是因为分配的内存将被重用,这在Web页面中是个好事,但在大型“硬核”脚本中却不是好事),分配的内存也永远不会被释放。