Le 11/03/2011 dans symfony

[Doctrine] Comment éviter les fuites de mémoire

Un des problèmes souvent rencontré avec Doctrine 1 est qu’il fait fait de nombreuses références cycliques, et que le garbage collector de PHP a du mal à réclamer sa mémoire.

La solution est simple, il faut explicitement libérer les Doctrine_Record, Doctrine_Collection et Doctrine_Query après utilisation (via la méthode free()).

Sachez qu’il existe une option… non documenté (wahou top secret #protips approaching!!) qui permet de libérer automatiquement la mémoire de vos Doctrine_Query :

public function configureDoctrine(Doctrine_Manager $manager)
{
  $manager->setAttribute(
    Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS, true
  );
}

Voilà c’était facile mais attention. Cette option est à utiliser avec précaution.

Déjà, ce n’est utile que si vous créez de nombreuses requêtes Doctrine dans votre action. Ça peut être le cas dans un batch par exemple. Ensuite, il faut savoir qu’après un ->execute(), vos Doctrine_Query ne seront vraiment plus du tout utilisable. 

Il est en effet courant de créer une Query une seule fois, et de l’appeler plusieur fois avec un tableau de paramètre différent. Avec l’option présenté précédemment, ça ne fonctionnera plus.

EDIT : Suite à un commentaire de Bastien, je découvre tout juste un autre #protips pour combler les fuites de mémoire de Doctrine !

Sur ma task (qui s’exécute par défaut dans l’environnement « dev »), je viens de gagner 150% de mémoire… L’astuce est de désactiver le profiler de Doctrine, dans votre database.yml :

# Disable profiler for import in task
  dev:
    doctrine:
      class: sfDoctrineDatabase
      param:
        profiler: false

J’ai envie de dire : awesome. Merci Rémiz.