旧それなりブログの跡地、画像やスタイルやJSなどが壊れてることがあります。

[Django] クエリのキャッシュ機能でメモリ的に失敗した件

2008年10月17日

Django クエリのキャッシュ機能の理解不足で
メモリの状況がひどいことになった。

例えば、こんな感じ↓のモデル構成で

# データ数は数百件程度
class SubModel(models.Model):
title = models.CharField(maxlength=255)
# データ数は50万件程度
class MainModel(models.Model):
sub_model = models.ForeignKey(SubModel)

こういうスクリプト↓を回した。

for i in models.MainModel.objects.all():
t = i.sub_model.title
# 何か処理をするが変数tはガベージコレクション行き

そうしたら、次の日にはメモリ使用量が98.7%になってた・・・。

「models.MainModel.objects.all() が展開された状態でのメモリ使用量」
を確認の上で、続行したはずなんだけどもなぁ・・・。

うーむむむ?

と、うなっててもしょーーーも無いので調べたところ、
以下の理由によるものだった

  • for文が終わるまでは、MainModel.objects.all() のリストはメモリから開放されない。
  • i.sub_modelを参照する度に上記のリストに紐付く形でメモリにキャッシュする。つまり、for文が終わるまで解放されない状況で、1ループの度にメモリ消費量が増えていく。
  • SubModelのデータは数百件であるが、メモリ上は正規化されずに各MainModelデータに紐付く形でキャッシュされる。例えば、今回だと50万件それぞれに対してメモリを消費する。

なるほどぅ。

なお、解決はどうしたかというと、カスタムSQLの実行により対処しましたとさ。
以上。