views:

405

answers:

1

I'm using Symfony 1.4 and Doctrine.

So far I had no problem running tasks with Symfony. But now that I have to import a pretty big amount of data and save them in the database, I get the infamous

"Fatal Error: Allowed memory size of XXXX bytes exhausted"

During this import I'm only creating new objects, setting a few fields and saving them.

I'm pretty sure it has something to do with the number of objects I'm creating when saving data. Unsetting those objects doesn't do anything though.

Are there any best practices to limit memory usage in Symfony?

+5  A: 

I've come across this, and there's a couple of techniques I found really helped with Doctrine's extensive memory usage.

1: Where possible, hydrate your Doctrine query results down to an array. You can do this as follows eg:

$query = self::createQuery("q")->
  ...
  ->setHydrationMode(Doctrine::HYDRATE_ARRAY)
  ->execute();

This forces Doctrine to NOT create large objects, but instead reduces it to an array. Obviously bear in mind that if you do this, you lose the ability to call methods etc, so this is only good if you're using it for reading field values etc.

2: Free your results after execution. This is documented in a tiny area of the Doctrine docs, but it's really helped out the import task I was using:

$query->free();

That's it. You can also do this on objects that you've created, eg $myObj->free(); and this forces Doctrine to remove all the circular references that it creates. Note that circular references are automatically freed from PHP 5.3 onwards on deletion of an object via the PHP scope or unset(), but before that you'll need to do it yourself.

Unsetting variables after you've used them also helps, although do this in conjunction with the free() method above as mentioned, as unset() won't clear the circular refs otherwise.

richsage
free() does help a lot, thanks!
Guillaume Flandre