如果我的代码看起来像这样(这里是Laravel代码,但它应该适用于一般情况):
class SomeClass
{
public function doSomething(array $data)
{
foreach ($data as $item) {
$this->doSomethingWithItem($item);
}
}
private function doSomethingWithItem($item)
{
$model = SomeModel::make($item);
// ... some other stuff
$model->save();
}
}
所以我的问题是,如果$data
是一个非常大的集合(在我的实际实现中它是一个生成器),内存使用随着数据项的数量线性增加。
既然$model
是一个局部变量,只引用那里不应该垃圾收集?我甚至在最后尝试了unset($model)
来强迫它释放,但它没有效果。
如何在不增加内存使用的情况下使用这种模式?由于我没有存储任何数据结构,内存使用量不应该随着每次迭代而增加,对吗?
我错过了什么吗?
IIRCunset()
不强制GC,它只是删除引用。你可以调用gc_collect_cycles()
来强制。
注:另一种方法是将数据分块,这也将允许比内存更大的数据集。
编辑:再通读一遍之后,您只是试图摆脱数据的"包装器"(模型)。数据仍然存在于内存中,因为$item
实际上占用了内存,并且从未被销毁,并且存在于doSomething()
的作用域中。