如何强行释放字典使用的内存?

问题描述 投票:4回答:1

我正在研究一个Python脚本,该脚本查询几个不同的数据库以整理数据并将所述数据持久保存到另一个数据库。该脚本从大约15个不同数据库中的数百万条记录中收集数据。为了尝试加快脚本速度,我提供了一些缓存功能,归结为拥有可容纳一些经常查询的数据的字典。字典包含键值对,其中键是根据数据库名称,集合名称和查询条件生成的哈希,而值是从数据库检索的数据。例如:

[{123456789: {_id: '1', someField: 'someValue'}},其中123456789是哈希,{_id: '1', someField: 'someValue'}是从数据库检索到的数据。

将这些数据保存在本地字典中意味着,我不必每次都查询数据库(这可能很慢,而不必每次都查询数据库),而是可以在本地访问一些经常查询的数据。如前所述,查询很多,因此字典可能会变得非常大(几个GB)。我有一些代码使用psutil来查看运行脚本的计算机上有多少可用内存,如果可用内存低于某个阈值,则清除字典。清除字典的代码是:

cached_documents.clear()
cached_documents = None
gc.collect()
cached_documents = {}

我应该指出,cached_documents是一个局部变量,该变量被传递到所有访问或添加到缓存的方法中。不幸的是,这似乎不足以适当地释放内存,因为即使调用了上面的代码后,Python仍然占用大量额外的内存。您可以在此处查看内存使用情况的配置文件:

enter image description here

[值得注意的事实是,清除字典的前几次,我们向系统释放了大量内存,但是随后的每次时间似乎都更少,这时内存使用量趋于平缓,因为缓存被非常频繁地清除。因为Python占用大量内存,所以可用内存在阈值之内。

在清除字典时是否有一种方法可以强制Python正确释放内存,从而避免使用扁平衬里?任何提示表示赞赏。

python dictionary memory memory-management memory-leaks
1个回答
0
投票

根据我对原始帖子的评论,我进行了一些更改。

如评论中所述,在进程结束之前,Python似乎无法可靠地将内存返回给操作系统。在某些应用程序中,这意味着您可以启动一个单独的进程来进行内存密集型工作。有关更多详细信息,请参见Releasing memory in Python

不幸的是,这不适用于我的情况,因为整个要点是在需要时将数据存储在内存中。

由于Python保留了一些分配的内存,并使其可用于其他Python对象,因此我更新了脚本的标准以清除缓存。我没有基于可用的系统内存,而是根据缓存大小设置了清除缓存的条件。理由是,我可以继续填充缓存并重新使用Python持有的内存。我通过对问题图中的缓存被清除的前几次大致平均值求出缓存大小阈值,然后略微减少了数量以增加一点余地(例如,大小为10的缓存可以使用不同的数量内存的大小取决于缓存中的内容)。

这比根据可用内存清除缓存不安全,因为缓存可能会变得大于系统上的可用内存,从而导致内存不足错误;特别是如果其他进程在需要大量内存的系统上运行,但是对于我的用例来说,这是一个适当的权衡。

现在,根据缓存的大小而不是可用的系统内存来清除缓存,我似乎能够利用Python保留内存的优势。尽管这可能不是一个完美的答案,但就我而言,它似乎可行。

© www.soinside.com 2019 - 2024. All rights reserved.