DoctrineでFatal error: Allowed memory size of ???? bytes exhausted を回避する

PHPでDoctrineを多用するようになったら、メモリが足りないというエラーが頻発してきました。

Doctrineそのものが3MBほど使うのは仕方ないとしても、クエリやレコード追加する度に使用メモリが増えつづけるのはいただけない。

不要メモリ削除にチャレンジしてみました。
まずは、一番簡単な方法。

例)
$query = Doctrine_Query::create()
->from(‘SomeModel’)
->where(…);
$rs = $query->execute();

// 使用後に、ここで参照を止めてみる
$rs = null;
$query = null;

通常はスコープをなくせばいいはずなのに、どんどん使用メモリが増えていきます。

さらに調べると、Doctrine_Recordが生成される際、Doctrine_Table_Repositoryに自分を登録しているではありませんか・・・

Doctrine_Query、Doctrine_Collection、Doctrine_Recordにはfreeメソッドがありました。特にDoctrine_Collectionでは、freeメソッドの引数deepをtrueにすることで、子のDoctrine_Recordのリレーション先のfreeまでやってくれそうです。

例)
$query = Doctrine_Query::create()
->from(‘SomeModel’)
->where(…);
$rs = $query->execute();

// 使用後に、Repositoryから削除し、参照も止めてみる
$rs->free(true);
$rs = null;
$query->free();
$query = null;

これで使用メモリは増えなくなり、スッキリしました。

ちなみに、そもそもDoctrine_Table_Repositoryに登録しない設定はないのかとしらべましたが、そんなものはありませんでした。

若干面倒ですが、freeしてnullするしかなさそうです。

(nullは、スコープが外れれば同じことなので、よほどシビアでなければやらなくても良い)