为什么这个Python(Django)代码吃掉了内存?
为什么这段代码吃掉了内存?当我运行它时,它每次循环都会消耗更多的内存,并且我拥有300000个循环。我使用Windows和Python 2.6。为什么这个Python(Django)代码吃掉了内存?
def LoadVotes(self):
old_votes=Votes.objects.all()
amount=old_votes.count()
print 'Amount of votes is: ' + str(amount)
c=0
for row in old_votes:
try:
new_id_user=LegacyUserId.objects.get(legacy_id=row._login)
except LegacyUserId.DoesNotExist:
string=" user with old id "+str(row._login)+" does not match new user id /n"
log=open('log_add_old_votes.txt','a')
log.write(string)
continue
try:
new_id_media=LegacyMedia.objects.get(legacy_id=row.media_file_id)
except new_id_media.DoesNotExist:
log_text='old media with ID:'+str(row.media_file_id)+' is not found in relation with new media \n'
log=open('log_add_old_votes.txt','a')
log.write(log_text)
continue
mo=MediaObject.objects.get(pk=new_id_media.object_id)
new_votes_item, created=Mark.objects.get_or_create(user=new_id_user.user, media_object=mo, defaults={'mark':int(row.rate)*2})
c=c+1
i=amount-c
print '\rRemain:',
stdout.write("%d" % i)
stdout.flush()
大概是因为它加载的每Vote
对象在数据库中,然后通过这些票和加载LegacyUserId
S表示每一个迭代,并为每一个LegacyMedia
对象。
如果您拥有的数据量很大,或者这些对象很大,则会占用大量内存。
我不会惊讶,如果LegacyMedia
本身是一个很大的对象。
YE但每个循环都必须清除变量。相反,它正在降我的记忆。也许这是因为我没有关闭日志文件和每个循环它再次打开文件,并采取莫内存它? 我没有使用log.close() – Pol 2010-07-16 19:30:11
你永远不会关闭你打开的文件。你应该这样做文件访问
with open('log_add_old_votes.txt','a') as log:
log.write(string)
这将自动关闭文件对象,为你一旦你完成它。您还将为每条日志消息使用相同的文件,因此您可以将open移至循环前面并在完成之前使用同一个文件对象。
我不确定Vote模型是什么样子。但是你只对来自投票(_login和media_file_id)的两个属性感兴趣。因此,您可以考虑使用值或values_list查询集API - 这样您只需选择所需的字段,并且不会为每行创建一个对象。
另外,根据您拥有的LegacyUserId或LegacyMedia行数量多少,如果您有外键,您可以考虑直接通过连接选择这些行,而不是迭代投票,然后在发出新查询时发出新的查询ID的存在。
最后,这不会影响内存,但考虑使用python logging而不是当前的方法。 (或者至少在函数启动时打开文件一次,而不是每次需要写入时)。
从底部开始,一次删除一行(您可以使用二进制搜索来加速该错误),直到问题消失。应该很容易找出哪条线正在吃掉记忆。 – Brian 2010-07-16 19:25:10