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は、スコープが外れれば同じことなので、よほどシビアでなければやらなくても良い)