Python在删除字典中的项目后回收内存

Posted

技术标签:

【中文标题】Python在删除字典中的项目后回收内存【英文标题】:Python reclaiming memory after deleting items in a dictionary 【发布时间】:2011-04-25 12:59:10 【问题描述】:

我在 Python 中有一个相对较大的字典,并且希望不仅能够从中删除项目,而且实际上 reclaim 从我的程序中的这些删除中恢复内存。我遇到了一个问题,虽然我从字典中删除了项目,甚至手动运行了垃圾收集器,但 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 并没有继续调整字典的大小。我的问题是,有什么简单的方法可以解决这个问题,还是我可能需要更认真地重新考虑如何编写程序?

【问题讨论】:

你是如何测量内存消耗的? 没什么花哨的 - Ubuntu 中的系统监视器 在 Windows XP SP3 上的 Python 2.6.5 上运行 gc.collect() 似乎释放了大约 50% 的内存 @Nick T:Windows 将释放的进程内存释放回操作系统以供使用,Linux 不会,因此这是预期的行为。他们俩都在为自己的目的做“正确的事”。 相关:Python: garbage collection fails?How can I explicitly free memory in Python? 【参考方案1】:

Python 是否将此内存返回给底层操作系统有很多因素,这可能是您试图判断内存是否被释放的方式。 CPython 有一个池分配器系统,它倾向于保留已释放的内存,以便可以有效地重用它(但从操作系统的角度来看,这些后续分配不会增加你的内存占用),这可能就是你的再看。

此外,在某些 unix 平台上,进程不会将释放的内存释放回操作系统,直到应用程序关闭(或发生其他一些重要事件)。即使您处于整个池已被释放的情况(因此 Python 可能决定释放它而不是为将来的对象保持打开状态),操作系统仍然不会释放此内存以供其他进程使用(但可用于在原始过程中进一步重新分配)。一般来说,这有利于减少内存碎片并且没有太多的缺点,因为未使用的进程内存将被分页到磁盘。 Windows 确实将进程内存释放回操作系统以供任何新分配使用(然后您可以在任务管理器中看到),因此在 Windows 上尝试此操作可能会出现给你不一样的结果。

最后,如何管理释放的进程内存是操作系统的职权范围,并且使用了各种方案(有利有弊),因此仅查看您选择的系统信息工具不一定会告诉您全部真相。

【讨论】:

【参考方案2】:

如果从字典中删除项目,Python 不会重新调整字典大小,这是对的。这与 OS 内存管理和垃圾收集无关,它是 Python 的 dict 数据结构的实现细节。

一种解决方法是通过复制旧字典来创建新字典。查看这个精彩的视频了解更多信息:http://pyvideo.org/video/276/the-mighty-dictionary-55(大约 26:30 有答案)。

【讨论】:

以上是关于Python在删除字典中的项目后回收内存的主要内容,如果未能解决你的问题,请参考以下文章

python显示float不可回收

python如何进行内存管理

基于python中嵌套字典中的键删除项目

根据python中嵌套字典中的键删除项目

python的内存驻留机制(小数据池)

Python垃圾回收机制 总结