【问题标题】:Python reclaiming memory after deleting items in a dictionaryPython在删除字典中的项目后回收内存
【发布时间】: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 memory-management


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-14
      • 1970-01-01
      • 2022-01-15
      • 2013-12-23
      相关资源
      最近更新 更多