当前位置: 首页 > 面试题库 >

在django中进行大型查询(或一系列查询)后,为什么不将内存释放到系统中?

柳培
2023-03-14
问题内容

首先,DEBUG = Falsesettings.py中,这样connections['default'].queries就不会增长,直到耗尽所有内存为止。

首先,我们Userdjango.contrib.auth.models.User10000个用户(每个名为’test#’,其中#是1到10000之间的数字)加载了表格。

这是视图:

from django.contrib.auth.models import User
from django.http import HttpResponse

import time

def leak(request):
    print "loading users"

    users = []
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())
    users += list(User.objects.all())

    print "sleeping"
    time.sleep(10)

    return HttpResponse('')

我已经将上面的视图附加到/leak/url上并启动了开发服务器(DEBUG = False,并且我已经测试过了,它与运行开发服务器与其他实例 无关
)。

运行后:

% curl http://localhost:8000/leak/

ps aux下面的输出中可以看到,runserver进程的内存增长到大约大小,然后保持在该级别。

USER       PID %CPU %MEM    VSZ    RSS TTY      STAT START   TIME COMMAND
dlamotte 25694 11.5 34.8 861384 705668 pts/3    Sl+  19:11   2:52 /home/dlamotte/tmp/django-mem-leak/env/bin/python ./manage.py runserver

然后,在上面运行上面的curl命令似乎并没有增加实例的内存使用量(我是从真正的内存泄漏中期望的?),必须重新使用内存吗?但是,我觉得这里没有将内存释放到系统中是有问题的(但是,我知道python不释放内存可能会有更好的性能)。

在此之后,我天真地尝试查看python是否会释放它分配的大块内存。因此,我尝试通过python会话进行以下操作:

>>> a = ''
>>> a += 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' * 10000000
>>> del a

内存已a += ...按预期分配在行上,但是del a发生这种情况时,将释放内存。为什么django查询集的行为不同?django打算这样做吗?有没有办法改变这种行为?

我实际上花了两天时间调试了此行为,却不知道下一步该怎么做(我学会了使用guppy和objgraph,这似乎并没有指出我可以弄清楚的有趣之处)。

更新: 这可能只是工作中的python内存管理,与Django无关(建议在django-
users邮件列表中使用),但是我想通过某种方式在Django外部的python中复制它来进行确认。

更新: 使用python 2.6.5版本


问题答案:

我决定将我的评论转变为答案,以使事情变得更清楚。

从Python
2.5开始,CPython内存分配跟踪小型对象分配器的内部内存使用情况,并尝试将完全空闲的竞技场返回给基础OS。这在大多数情况下都有效,但是对象无法在内存中移动的事实意味着碎片可能是一个严重的问题。

尝试以下实验(我使用3.2,但如果使用xrange,则2.5+应该类似):

# Create the big lists in advance to avoid skewing the memory counts
seq1 = [None] * 10**6 # Big list of references to None
seq2 = seq1[::10]

# Create and reference a lot of smaller lists
seq1[:] = [[] for x in range(10**6)] # References all the new lists
seq2[:] = seq1[::10] # Grab a second reference to 10% of the new lists

# Memory fragmentation in action
seq1[:] = [None] * 10**6 # 90% of the lists are no longer referenced here
seq2[:] = seq1[::10] # But memory freed only after last 10% are dropped

请注意,即使您删除对seq1和的引用seq2,上述序列也可能会使您的Python进程拥有大量额外的内存。

当人们谈论PyPy使用的内存少于CPython时,这是他们所谈论内容的重要部分。因为PyPy在后台不使用直接指针引用,所以它可以使用压缩GC,从而避免了很多碎片问题,并更可靠地将内存返回给OS。



 类似资料:
  • 一个简单的公交查询系统。可分线路查询、站站查询,也有收藏、地图信息、系统设置几大功能。 开发者说:有做公交查询系统,或地图方面应用的可以下载参考,希望能帮助到你。 [Code4App.com]

  • script/下的memstat.sh或者ps_mem.py都可以查看系统的内存情况,两个工具都需要root权限。

  • 我正在尝试为我的网站创建一个最喜欢的系统。我有一个用户表、作业表和一个收藏夹表。当用户将作业添加到他们的收藏夹中时,他们的用户ID和jobsId将保存到favorites表中。当用户想要查看他们的收藏夹时,我一直试图选择favorites表中与当前用户具有相同userId的所有行。然后,我需要从这些行中选择JobID,并选择job表中具有匹配JobID的所有行。 我一直在尝试这个查询的变体,但没有

  • #!/bin/bash # Get current swap usage for all running processes # Erik Ljungstrom 27/05/2011 # Modified by Mikko Rantalainen 2012-08-09 # Pipe the output to "sort -nk3" to get sorted output # Modified

  • 问题内容: 我试图弄清楚如何在Django中编写“不在”风格的查询。例如,我正在考虑的查询结构将如下所示。 假设模型名为table1和table2,django语法会是什么样? 问题答案: 排除功能的作用类似于你要查询的运算符。该属性告诉查询以返回value_list一级列表。因此,…最后,你IDs将从中获得列表,你将用该列表定义用户中的条件,该条件将被exclude函数拒绝。

  • 问题内容: 我将Ebean与Play 2 Framework结合使用,并得到了两种模型:用户模型和书本模型。用户模型与书籍模型以一对多关系连接。因此,每个用户可以拥有很多书,甚至根本没有书。书籍模型本身也具有属性。现在,我想在用户模型中创建一个查询,该查询仅返回具有某些属性书的用户。例如:一个属性可能是条件,例如new或used。现在,给我所有拥有新状态书籍的用户。是否可以使用Ebean方法创建这