6

我有一个非常简单的脚本,它分配内存,dels唯一引用一个相当大的对象,同时打印heapypidstat报告。运行脚本后,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)

输出如下所示:

================================
在做任何事情之前
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 命令
01:05:20 PM 5360 0.44 0.00 44768 9180 0.11 蟒蛇
+++++++++++++++++++++++++++++++++++
一组 19760 个对象的分区。总大小 = 1591024 字节。
 索引计数 % 大小 % 累积 % 种类(类/类字典)
     0 19760 100 1591024 100 1591024 100 力量
================================
================================
将所有文档提取到内存后
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 命令
01:05:21 PM 5360 8.95 0.00 318656 279120 3.49 蟒蛇
+++++++++++++++++++++++++++++++++++
一组 7431665 个对象的分区。总大小 = 178359960 字节。
 索引计数 % 大小 % 累积 % 种类(类/类字典)
     0 7431665 100 178359960 100 178359960 100 整数
================================
================================
释放文档后
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 命令
01:05:29 PM 5360 40.23 0.00 499984 460480 5.77 蟒蛇
+++++++++++++++++++++++++++++++++++
一组 19599 个对象的分区。总大小 = 1582016 字节。
 索引计数 % 大小 % 累积 % 种类(类/类字典)
     0 19599 100 1582016 100 1582016 100 力量
================================

如何确保将内存返回给操作系统?

4

2 回答 2

3

内存在进程内可用于重用的python时间与将其释放到操作系统的时间可能有所不同。特别是,标准 Python 解释器 (CPython) 为特定类型的对象维护自己的池和空闲列表。它将重用这些池本身中的内存,但一旦使用就不会将其释放给操作系统。

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

于 2012-08-14T17:29:12.063 回答
1

如何确保将内存返回给操作系统?

一般不会。Python 在“arenas”中分配内存,即使在解释器中删除了引用,它也会保留该内存区域以供以后使用。我认为在较新版本的 python 中有一种机制可以在它们完全为空的情况下取消声明竞技场。但是您无法控制对象的放置位置。

于 2012-08-14T17:28:58.210 回答