Garbage collection / reduce memory usage

Viewed 268

If I have code that looks something like this (Laravel code here but it should apply generally):

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();
    }
}

So my problem is that, if $data is a very large set (in my real implementation it is a generator) memory usage increases linearly with the number of data items.

Since $model is a local variable and only referenced there shouldn't it be garbage collected? I've even tried unset($model) at the end to force it's release but it has no effect.

How can I use this kind of pattern without increasing my memory usage? Since I'm not storing any data structures memory usage should not increase with each iteration should it?

Am I missing something here?

1 Answers

IIRC unset() doesn't force the GC, it just removes the reference. You can call gc_collect_cycles() to force it.

Side Note: Another approach would be to chunk the data, that would also allow for datasets larger than memory.

Edit: After reading through this another time, you're only trying to get rid of the 'wrapper' (model) of the data. The data still exists in memory because $item is what actually takes up memory and is never destroyed and exists in scope in doSomething().

Related