例如,我有一个产生许多整数的代码。
import sys
import random
a = [random.randint(0, sys.maxint) for i in xrange(10000000)]
运行后我得到了VIRT 350M,RES 320M(以htop查看)。
然后我做:
del a
但是记忆仍然是VIRT 272M,RES 242M(产生整数之前是VIRT 24M,RES 6M)。
一个进程的pmap说有很多[anon]内存。
Python 3.4没有这样的行为:当我在这里删除列表时,内存可以释放!
会发生什么? python会将整数留在内存中吗?
答案 0 :(得分:1)
这是我如何复制它。如果我启动python 2.7,解释器使用大约4.5 MB的内存。 (我引用" Real Mem"来自Mac OS X Activity Monitor.app的值。)
>>> a = [random.randint(0, sys.maxint) for i in xrange(10000000)]
现在,内存使用量约为305.7 MB。
>>> del a
删除a
似乎对内存没有影响。
>>> import gc
>>> gc.collect() # perform a full collection
现在,内存使用量为27.7 MB。有时,第一次拨打collect()
似乎没有做任何事情,但第二次collect()
电话会清理。
但是,这种行为是设计的, Python并没有泄漏。 This old FAQ在effbot.org上解释了更多关于发生了什么的事情:
“For speed”,Python维护整数对象的内部空闲列表。不幸的是,这个免费清单既是不朽的,也是无限的。花车也使用不朽的&无限的免费清单。
基本上,python将整数视为单例,假设您可能不止一次使用它们。
考虑一下:
# 4.5 MB
>>> a = [object() for i in xrange(10000000)]
# 166.7 MB
>>> del a
# 9.1 MB
在这种情况下,python很明显python没有将object
保留在内存中,并且删除a
会触发垃圾收集,从而清除所有内容。
我记得,python实际上会永远保留内存中的低值整数(0 - 1000左右)。这可以解释为什么gc.collect()
调用没有返回与删除objects
列表一样多的内存。
我仔细研究了PEPs以找出Python3与众不同的原因。但是,我没有看到任何明显的东西。如果真的想知道,你可以在源代码中挖掘。
在Python 3中可以说,数字单例行为已经改变,或者垃圾收集器变得更好。
Python 3中有很多东西比较好。