Case 1 is logic, because you "magic" call a relation that isn't loaded before Laravel will load the relation. It will not automaticly free it during the loop because it doesn't know that it isn't needed anymore.
Case 2 calls the query builder on the object, get the set from it and place that in a variable. After each iteration the $songs variable is cleared and so the memory isn't needed. Because you call the relation function for the query builder but not the relation itself it isn't stored on the $album. That is the reason you don't get an increase in memory.
Case 3, everything is loaded on the start so the memory keeps the same.
Case 4, same idea as case 1. You load the relation and the $album variable isn't removed so the memory is increasing.
Case 5, same as case 3. Everything is loaded on the start so the memory keeps the same.
In basic the difference is that $model->relation will load the relation if that isn't done yet and save the data on the model. While $model->relation()->get() will use the query builder where you get the result while it isn't stored in the $model variable.
@tvbeek I try to unset the variables every iteration, the memory still grows, is there any way to free the memory?
$albums = Album::take(10000)->get();
foreach ($albums as $album) {
$songs = $album->songs; // cause memory leak
unset($songs);
unset($album); // can't free the memory, I think in this case is memory leak
}
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community