如何强行释放字典使用的内存?
How to forcibly free memory used by dictionary?
我正在开发一个 Python 脚本,该脚本查询多个不同的数据库以整理数据并将所述数据保存到另一个数据库。该脚本从大约 15 个不同数据库中的数百万条记录中收集数据。为了尝试加快脚本速度,我加入了一些缓存功能,归结为拥有一个包含一些经常查询的数据的字典。字典包含键值对,其中键是根据数据库名称、集合名称和查询条件生成的哈希,值是从数据库中检索到的数据。例如:
{123456789: {_id: '1', someField: 'someValue'}}
其中 123456789
是散列,{_id: '1', someField: 'someValue'}
是从数据库中检索的数据。
将此数据保存在本地字典中意味着我不必每次都查询数据库,这可能很慢,我可以在本地访问一些经常查询的数据。如前所述,有很多查询,所以字典会变得非常大(几千兆字节)。我有一些代码使用 psutil
查看机器上有多少可用内存 运行 脚本,如果可用内存低于某个阈值,我会清除字典。清除字典的代码是:
cached_documents.clear()
cached_documents = None
gc.collect()
cached_documents = {}
我应该指出 cached_documents
是一个局部变量,它被传递到所有访问或添加到缓存的方法中。不幸的是,这似乎不足以正确释放内存,因为 Python 仍然占用大量额外内存,即使在调用上述代码之后也是如此。您可以在此处查看内存使用情况:
值得注意的是,前几次字典被清除,我们向系统释放了大量内存,但随后的每次似乎都更少,此时内存使用率趋于平缓,因为缓存得到由于 Python 占用大量内存,可用内存在阈值内,因此非常频繁地清除。
有没有办法强制Python在清理字典时正确释放内存,从而避免平衬?如有任何提示,我们将不胜感激。
根据我原来的评论post,我做了一些修改。
如评论中所述,在进程结束之前,Python 似乎无法可靠地 return 向操作系统提供内存。在某些应用程序中,这意味着您可以启动一个单独的进程来执行内存密集型工作。有关详细信息,请参阅 Releasing memory in Python。
不幸的是,这不适用于我的情况,因为重点是在需要时将数据存储在内存中。
由于 Python 保留了一些分配的内存并使其可用于其他 Python 对象,我更新了我的脚本的标准以清除缓存。我没有根据可用的系统内存来设置条件,而是根据缓存大小设置清除缓存的条件。理由是我可以继续填充缓存并重新使用 Python 持有的内存。我通过在我的问题的图表中清除缓存的前几次粗略平均找到缓存大小阈值,然后稍微减少数量以增加一点回旋余地(例如,大小为 10 的缓存可以使用不同的数量基于缓存内部内容的内存)。
这比根据可用内存清除缓存更不安全,因为缓存有可能增长到大于系统上的可用内存,从而导致内存不足错误;特别是如果系统上的其他进程 运行 需要大量内存,但对于我的用例来说,这是一个合适的权衡。
现在根据缓存的大小而不是可用的系统内存清除缓存,我似乎可以利用 Python 保留内存。虽然这可能不是一个完美的答案,但就我而言,它似乎有效。
我正在开发一个 Python 脚本,该脚本查询多个不同的数据库以整理数据并将所述数据保存到另一个数据库。该脚本从大约 15 个不同数据库中的数百万条记录中收集数据。为了尝试加快脚本速度,我加入了一些缓存功能,归结为拥有一个包含一些经常查询的数据的字典。字典包含键值对,其中键是根据数据库名称、集合名称和查询条件生成的哈希,值是从数据库中检索到的数据。例如:
{123456789: {_id: '1', someField: 'someValue'}}
其中 123456789
是散列,{_id: '1', someField: 'someValue'}
是从数据库中检索的数据。
将此数据保存在本地字典中意味着我不必每次都查询数据库,这可能很慢,我可以在本地访问一些经常查询的数据。如前所述,有很多查询,所以字典会变得非常大(几千兆字节)。我有一些代码使用 psutil
查看机器上有多少可用内存 运行 脚本,如果可用内存低于某个阈值,我会清除字典。清除字典的代码是:
cached_documents.clear()
cached_documents = None
gc.collect()
cached_documents = {}
我应该指出 cached_documents
是一个局部变量,它被传递到所有访问或添加到缓存的方法中。不幸的是,这似乎不足以正确释放内存,因为 Python 仍然占用大量额外内存,即使在调用上述代码之后也是如此。您可以在此处查看内存使用情况:
值得注意的是,前几次字典被清除,我们向系统释放了大量内存,但随后的每次似乎都更少,此时内存使用率趋于平缓,因为缓存得到由于 Python 占用大量内存,可用内存在阈值内,因此非常频繁地清除。
有没有办法强制Python在清理字典时正确释放内存,从而避免平衬?如有任何提示,我们将不胜感激。
根据我原来的评论post,我做了一些修改。
如评论中所述,在进程结束之前,Python 似乎无法可靠地 return 向操作系统提供内存。在某些应用程序中,这意味着您可以启动一个单独的进程来执行内存密集型工作。有关详细信息,请参阅 Releasing memory in Python。
不幸的是,这不适用于我的情况,因为重点是在需要时将数据存储在内存中。
由于 Python 保留了一些分配的内存并使其可用于其他 Python 对象,我更新了我的脚本的标准以清除缓存。我没有根据可用的系统内存来设置条件,而是根据缓存大小设置清除缓存的条件。理由是我可以继续填充缓存并重新使用 Python 持有的内存。我通过在我的问题的图表中清除缓存的前几次粗略平均找到缓存大小阈值,然后稍微减少数量以增加一点回旋余地(例如,大小为 10 的缓存可以使用不同的数量基于缓存内部内容的内存)。
这比根据可用内存清除缓存更不安全,因为缓存有可能增长到大于系统上的可用内存,从而导致内存不足错误;特别是如果系统上的其他进程 运行 需要大量内存,但对于我的用例来说,这是一个合适的权衡。
现在根据缓存的大小而不是可用的系统内存清除缓存,我似乎可以利用 Python 保留内存。虽然这可能不是一个完美的答案,但就我而言,它似乎有效。