python—内存没有返回到内核

python—内存没有返回到内核,python,memory-management,memory-leaks,python-2.7,Python,Memory Management,Memory Leaks,Python 2.7,我有一个分配内存的非常简单的脚本,dels是对一个大对象的唯一引用,同时打印heapy和pidstat报告。运行脚本后,heapy告诉我应该没有太多内存被使用,而pidstat告诉我相反的情况: from guppy import hpy import time import sys import os ''' 1) print heapy and pidstat report after starting and before actually doing any work 2) alloc

我有一个分配内存的非常简单的脚本,
dels
是对一个大对象的唯一引用,同时打印
heapy
pidstat
报告。运行脚本后,heapy告诉我应该没有太多内存被使用,而pidstat告诉我相反的情况:

from guppy import hpy
import time
import sys
import os

'''
1) print heapy and pidstat report after starting and before actually doing any work
2) allocate some memory in a simple 2d array
3) print heapy and pidstat report
4) del the d2 array (attempt at garbage collection)
5) print heapy and pidstat report
6) sleep so pidstat can continue to be run to check on memory
'''

def pidstat(msg):
    print '==============================='
    print msg
    os.system('pidstat -r -p %s' % os.getpid())
    print '+++++++++++++++++++++++++++++++'
    print hpy().heap()[0]
    print '==============================='

pidstat('before doing anything')
docs = []
for doc in range(0, 10000):
    docs.append([j for j in range(0, 1000)])

pidstat('after fetching all the docs into memory')
del docs

pidstat('after freeing the docs')
time.sleep(60)
输出如下所示:

=============================== before doing anything Linux 2.6.38-15-generic (hersheezy) 08/14/2012 _x86_64_ (4 CPU) 01:05:20 PM PID minflt/s majflt/s VSZ RSS %MEM Command 01:05:20 PM 5360 0.44 0.00 44768 9180 0.11 python +++++++++++++++++++++++++++++++ Partition of a set of 19760 objects. Total size = 1591024 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 19760 100 1591024 100 1591024 100 str =============================== =============================== after fetching all the docs into memory Linux 2.6.38-15-generic (hersheezy) 08/14/2012 _x86_64_ (4 CPU) 01:05:21 PM PID minflt/s majflt/s VSZ RSS %MEM Command 01:05:21 PM 5360 8.95 0.00 318656 279120 3.49 python +++++++++++++++++++++++++++++++ Partition of a set of 7431665 objects. Total size = 178359960 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 7431665 100 178359960 100 178359960 100 int =============================== =============================== after freeing the docs Linux 2.6.38-15-generic (hersheezy) 08/14/2012 _x86_64_ (4 CPU) 01:05:29 PM PID minflt/s majflt/s VSZ RSS %MEM Command 01:05:29 PM 5360 40.23 0.00 499984 460480 5.77 python +++++++++++++++++++++++++++++++ Partition of a set of 19599 objects. Total size = 1582016 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 19599 100 1582016 100 1582016 100 str =============================== =============================== 在做任何事之前 Linux 2.6.38-15-generic(hersheezy)08/14/2012\u x86\u 64\u4(CPU) 01:05:20 PM PID minflt/s majflt/s VSZ RSS%MEM命令 下午1:05:20 5360 0.44 0.00 44768 9180 0.11 python +++++++++++++++++++++++++++++++ 一组19760个对象的分区。总大小=1591024字节。 索引计数%Size%累计%Kind(类/类的目录) 01976010015910241001591024100STR =============================== =============================== 将所有文档提取到内存后 Linux 2.6.38-15-generic(hersheezy)08/14/2012\u x86\u 64\u4(CPU) 01:05:21 PM PID minflt/s majflt/s VSZ RSS%MEM命令 下午1:05:21 5360 8.95 0.00 318656 279120 3.49 +++++++++++++++++++++++++++++++ 一组7431665对象的分区。总大小=178359960字节。 索引计数%Size%累计%Kind(类/类的目录) 0 7431665 100 178359960 100 178359960 100内部 =============================== =============================== 释放文档后 Linux 2.6.38-15-generic(hersheezy)08/14/2012\u x86\u 64\u4(CPU) 01:05:29 PM PID minflt/s majflt/s VSZ RSS%MEM命令 01:05:29下午5360 40.23 0.00 499984 460480 5.77 python +++++++++++++++++++++++++++++++ 一组19599个对象的分区。总大小=158016字节。 索引计数%Size%累计%Kind(类/类的目录) 0 1959910015820161001582016100街 =============================== 如何确保将此内存返回到操作系统

如何确保将此内存返回到操作系统


通常不会。Python在“竞技场”中分配内存,即使在解释器中删除了引用,它也会保留该内存竞技场以供以后使用。我认为,在较新版本的python中,有一种机制可以在竞技场完全为空时清除竞技场。但是您无法控制对象的放置位置。

python
进程中何时可以重用内存,以及何时将内存释放到操作系统中,这两者之间可能存在差异。特别是,标准Python解释器(CPython)为特定类型的对象维护自己的池和自由列表。它本身将重用这些池中的内存,但一旦被使用,就不会将其释放到操作系统中


有关更多详细信息,请参阅。

我相信答案可能与发布的问题相同。我真正的问题来自于一个长期运行的python守护进程,它在很短的时间内每天分配一吨内存(系统内存的约60%)。完成运行后,即使我清理了引用,内存使用率仍然很高。有什么建议吗?你发布的链接似乎在说,我不应该一开始就分配那么多内存……你有没有可能在第二个脚本中做需要大量内存的事情,或者类似的事情?或者在内存不足的处理开始时启动守护程序的第二个实例,然后在处理完成后退出(允许第二个实例继续运行)?@Hersheezy:这个答案听起来似乎有道理,但它是错误的。CPython有时会释放内存。看,是的,这是可行的。然而,我希望直接在python中实现一种特殊的缓存机制,因为守护进程的其他部分需要一些数据,这些数据是在运行后立即由内存不足部分获取/生成的。看起来我只是找错了方向:(@Sebastian.有没有办法知道在什么情况下可以/将释放内存?我的代码示例非常简单,但内存仍然没有被返回…在2005年。尽管可能会