许多进程(使用多进程包创建)将从Queue中抽出东西,并使用传递给队列的pr.id对请求进行处理.我相信内存泄漏可能在下面的代码中(但是它可能在队列的另一边的“工作者”代码中,尽管这不太可能,因为即使没有请求出现,内存大小也在增长 – 即当工作人员都阻止Queue.get()).
from requisitions.models import Requisition # our Django model from multiprocessing import Queue while True: # Wait for "N"ew requisitions,then pop them into the queue. for pr in Requisition.objects.all().filter(status=Requisition.STATUS_NEW): pr.set_status(pr.STATUS_WORKING) pr.save() queue.put(pr.id) time.sleep(settings.DAEMON_POLL_WAIT)
其中settings.DAEMON_POLL_WAIT = 0.01.
似乎如果我离开这个运行一段时间(即几天),Python进程将增长到无限大小,最终系统内存不足.
这里发生了什么(或者如何找到),更重要的是 – 如何运行这样的守护进程?
我的第一个想法是改变功能的动态,特别是通过将新的Requisition对象的检查放在django.core.cache缓存中,即
from django.core.cache import cache while True: time.sleep(settings.DAEMON_POLL_WAIT) if cache.get('new_requisitions'): # Possible race condition cache.clear() process_new_requisitions(queue) def process_new_requisitions(queue): for pr in Requisition.objects.all().filter(status=Requisition.STATUS_NEW): pr.set_status(pr.STATUS_WORKING) pr.save() queue.put(pr.id)
正在创建状态= STATUS_NEW的请求的进程可以执行cache.set(‘new_requisitions’,1)(或者我们可以捕获一个信号或Requisition.save()事件,其中正在创建一个新的请购单,然后将标志设置为缓存从那里).
然而,我不确定我在这里提出的解决方案是否解决了内存问题(这可能与垃圾收集有关),所以通过process_new_requisitions可以解决这个问题).
我很感谢任何想法和反馈.
解决方法
from django import db db.reset_queries()
也可以看看:
> “Debugging Django memory leak with TrackRefs and Guppy”由Mikko
Ohtamaa:
Django keeps track of all queries for
debugging purposes
(connection.queries). This list is
reseted at the end of HTTP request.
But in standalone mode,there are no
requests. So you need to manually
reset to queries list after each
working cycle
> “Why is Django leaking memory?” in Django FAQ – 它会谈关于将DEBUG设置为False,这总是很重要,以及关于使用db.reset_queries()清除查询列表,在像你这样的应用程序中很重要.