我在Python中有一个相对较大的字典,并且希望不仅能够从中删除项目,而且实际上从我的程序中的这些删除中回收内存。我正在遇到一个问题,虽然我从字典中删除了项目,甚至手动运行垃圾收集器,但Python似乎并没有释放内存本身。
一个简单的例子:
>>> tupdict = {}
# consumes around 2 GB of memory
>>> for i in xrange(12500000):
... tupdict[i] = (i,i)
...
# delete over half the entries, no drop in consumed memory
>>> for i in xrange(7500000):
... del tupdict[i]
...
>>> import gc
# manually garbage collect, still no drop in consumed memory after this
>>> gc.collect()
0
>>>
我想现在发生的事情是,虽然条目被删除并且垃圾收集器运行,但Python不会继续并调整字典的大小。我的问题是,有没有简单的方法,或者我可能需要更严肃地重新考虑如何编写我的程序?
答案 0 :(得分:18)
许多因素都会影响Python是否将此内存返回到底层操作系统,这可能是您尝试判断内存是否被释放的方式。 CPython有一个池化的分配器系统,它倾向于保留释放的内存,以便它可以以有效的方式重用(但是这些后续的分配不会从操作系统的角度增加内存占用量),这可能就是你的'重看。
此外,在某些unix平台上,在应用程序关闭(或发生其他重要事件)之前,进程不会将释放的内存释放回操作系统。即使您处于已释放整个池的情况下(因此Python可能决定释放它()而不是将其保持为未来对象打开),操作系统仍然不会释放此内存以供其他进程使用(但可用于在原始过程中进一步重新分配)。一般来说,这对于减少内存碎片并没有太大的缺点,因为未使用的进程内存将被分页到磁盘。 Windows 将进程内存释放回操作系统以供任何新分配(您可以在任务管理器中查看)使用,因此在Windows上尝试此操作可能出现给你一个不同的结果。
最后,如何管理解除分配的进程内存是操作系统的权限,并且使用了各种方案(具有上行和缺点),这样只需查看您选择的系统信息工具就不一定会告诉您全部真相。
答案 1 :(得分:6)
如果项目从字典中删除,那么Python不会重新调整字典大小。这与OS内存管理和垃圾收集无关,它是Python的dict数据结构的实现细节。
解决方法是通过复制旧字典来创建新字典。查看这个精彩视频了解更多信息:http://pyvideo.org/video/276/the-mighty-dictionary-55(26:30左右有答案)。